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_sha256())) {
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  X509 *cert = NULL;
402  BIO *mem = BIO_new_mem_buf(pem_str, -1);
403  if (!mem) {
404  av_log(NULL, AV_LOG_ERROR, "BIO_new_mem_buf failed\n");
405  return NULL;
406  }
407 
408  cert = PEM_read_bio_X509(mem, NULL, NULL, NULL);
409  if (!cert)
410  av_log(NULL, AV_LOG_ERROR, "Failed to parse certificate from string\n");
411 
412  BIO_free(mem);
413  return cert;
414 }
415 
416 
417 typedef struct TLSContext {
419  SSL_CTX *ctx;
420  SSL *ssl;
421  BIO_METHOD* url_bio_method;
422  int io_err;
423  char error_message[256];
425  socklen_t dest_addr_len;
426 } TLSContext;
427 
428 /**
429  * Retrieves the error message for the latest OpenSSL error.
430  *
431  * This function retrieves the error code from the thread's error queue, converts it
432  * to a human-readable string, and stores it in the TLSContext's error_message field.
433  * The error queue is then cleared using ERR_clear_error().
434  */
435 static const char* openssl_get_error(TLSContext *c)
436 {
437  int r2 = ERR_get_error();
438  if (r2) {
439  ERR_error_string_n(r2, c->error_message, sizeof(c->error_message));
440  } else
441  c->error_message[0] = '\0';
442 
443  ERR_clear_error();
444  return c->error_message;
445 }
446 
448 {
449  TLSContext *c = h->priv_data;
450  TLSShared *s = &c->tls_shared;
451 
452  if (s->is_dtls)
453  c->tls_shared.udp = sock;
454  else
455  c->tls_shared.tcp = sock;
456 
457  return 0;
458 }
459 
460 int ff_dtls_export_materials(URLContext *h, char *dtls_srtp_materials, size_t materials_sz)
461 {
462  int ret = 0;
463  const char* dst = "EXTRACTOR-dtls_srtp";
464  TLSContext *c = h->priv_data;
465 
466  ret = SSL_export_keying_material(c->ssl, dtls_srtp_materials, materials_sz,
467  dst, strlen(dst), NULL, 0, 0);
468  if (!ret) {
469  av_log(c, AV_LOG_ERROR, "Failed to export SRTP material, %s\n", openssl_get_error(c));
470  return -1;
471  }
472  return 0;
473 }
474 
475 static int print_ssl_error(URLContext *h, int ret)
476 {
477  TLSContext *c = h->priv_data;
478  int printed = 0, e, averr = AVERROR(EIO);
479  if (h->flags & AVIO_FLAG_NONBLOCK) {
480  int err = SSL_get_error(c->ssl, ret);
481  if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
482  return AVERROR(EAGAIN);
483  }
484  while ((e = ERR_get_error()) != 0) {
485  av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(e, NULL));
486  printed = 1;
487  }
488  if (c->io_err) {
489  av_log(h, AV_LOG_ERROR, "IO error: %s\n", av_err2str(c->io_err));
490  printed = 1;
491  averr = c->io_err;
492  c->io_err = 0;
493  }
494  if (!printed)
495  av_log(h, AV_LOG_ERROR, "Unknown error\n");
496  return averr;
497 }
498 
499 static int tls_close(URLContext *h)
500 {
501  TLSContext *c = h->priv_data;
502  if (c->ssl) {
503  SSL_shutdown(c->ssl);
504  SSL_free(c->ssl);
505  }
506  if (c->ctx)
507  SSL_CTX_free(c->ctx);
508  if (!c->tls_shared.external_sock)
509  ffurl_closep(c->tls_shared.is_dtls ? &c->tls_shared.udp : &c->tls_shared.tcp);
510  if (c->url_bio_method)
511  BIO_meth_free(c->url_bio_method);
512  return 0;
513 }
514 
515 static int url_bio_create(BIO *b)
516 {
517  BIO_set_init(b, 1);
518  BIO_set_data(b, NULL);
519  BIO_set_flags(b, 0);
520  return 1;
521 }
522 
523 static int url_bio_destroy(BIO *b)
524 {
525  return 1;
526 }
527 
528 static int url_bio_bread(BIO *b, char *buf, int len)
529 {
530  TLSContext *c = BIO_get_data(b);
531  TLSShared *s = &c->tls_shared;
532  int ret = ffurl_read(c->tls_shared.is_dtls ? c->tls_shared.udp : c->tls_shared.tcp, buf, len);
533  if (ret >= 0) {
534  if (s->is_dtls && s->listen && !c->dest_addr_len) {
535  int err_ret;
536 
537  ff_udp_get_last_recv_addr(s->udp, &c->dest_addr, &c->dest_addr_len);
538  err_ret = ff_udp_set_remote_addr(s->udp, (struct sockaddr *)&c->dest_addr, c->dest_addr_len, 1);
539  if (err_ret < 0) {
540  av_log(c, AV_LOG_ERROR, "Failed connecting udp context\n");
541  return err_ret;
542  }
543  av_log(c, AV_LOG_TRACE, "Set UDP remote addr on UDP socket, now 'connected'\n");
544  }
545 
546  return ret;
547  }
548  BIO_clear_retry_flags(b);
549  if (ret == AVERROR_EXIT)
550  return 0;
551  if (ret == AVERROR(EAGAIN))
552  BIO_set_retry_read(b);
553  else
554  c->io_err = ret;
555  return -1;
556 }
557 
558 static int url_bio_bwrite(BIO *b, const char *buf, int len)
559 {
560  TLSContext *c = BIO_get_data(b);
561  int ret = ffurl_write(c->tls_shared.is_dtls ? c->tls_shared.udp : c->tls_shared.tcp, buf, len);
562  if (ret >= 0)
563  return ret;
564  BIO_clear_retry_flags(b);
565  if (ret == AVERROR_EXIT)
566  return 0;
567  if (ret == AVERROR(EAGAIN))
568  BIO_set_retry_write(b);
569  else
570  c->io_err = ret;
571  return -1;
572 }
573 
574 static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
575 {
576  if (cmd == BIO_CTRL_FLUSH) {
577  BIO_clear_retry_flags(b);
578  return 1;
579  }
580  return 0;
581 }
582 
583 static int url_bio_bputs(BIO *b, const char *str)
584 {
585  return url_bio_bwrite(b, str, strlen(str));
586 }
587 
589 {
590  TLSContext *c = h->priv_data;
591  BIO *bio;
592  c->url_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "urlprotocol bio");
593  BIO_meth_set_write(c->url_bio_method, url_bio_bwrite);
594  BIO_meth_set_read(c->url_bio_method, url_bio_bread);
595  BIO_meth_set_puts(c->url_bio_method, url_bio_bputs);
596  BIO_meth_set_ctrl(c->url_bio_method, url_bio_ctrl);
597  BIO_meth_set_create(c->url_bio_method, url_bio_create);
598  BIO_meth_set_destroy(c->url_bio_method, url_bio_destroy);
599  bio = BIO_new(c->url_bio_method);
600  BIO_set_data(bio, c);
601 
602  SSL_set_bio(c->ssl, bio, bio);
603 }
604 
605 static void openssl_info_callback(const SSL *ssl, int where, int ret) {
606  const char *method = "undefined";
607  TLSContext *c = (TLSContext*)SSL_get_ex_data(ssl, 0);
608 
609  if (where & SSL_ST_CONNECT) {
610  method = "SSL_connect";
611  } else if (where & SSL_ST_ACCEPT)
612  method = "SSL_accept";
613 
614  if (where & SSL_CB_LOOP) {
615  av_log(c, AV_LOG_DEBUG, "Info method=%s state=%s(%s), where=%d, ret=%d\n",
616  method, SSL_state_string(ssl), SSL_state_string_long(ssl), where, ret);
617  } else if (where & SSL_CB_ALERT) {
618  method = (where & SSL_CB_READ) ? "read":"write";
619  av_log(c, AV_LOG_DEBUG, "Alert method=%s state=%s(%s), where=%d, ret=%d\n",
620  method, SSL_state_string(ssl), SSL_state_string_long(ssl), where, ret);
621  }
622 }
623 
625 {
626  int ret = 1, r0, r1;
627  TLSContext *c = h->priv_data;
628 
629  c->tls_shared.udp->flags &= ~AVIO_FLAG_NONBLOCK;
630 
631  r0 = SSL_do_handshake(c->ssl);
632  if (r0 <= 0) {
633  r1 = SSL_get_error(c->ssl, r0);
634 
635  if (r1 != SSL_ERROR_WANT_READ && r1 != SSL_ERROR_WANT_WRITE && r1 != SSL_ERROR_ZERO_RETURN) {
636  av_log(c, AV_LOG_ERROR, "Handshake failed, r0=%d, r1=%d\n", r0, r1);
637  ret = print_ssl_error(h, r0);
638  goto end;
639  }
640  } else {
641  av_log(c, AV_LOG_TRACE, "Handshake success, r0=%d\n", r0);
642  }
643 
644  /* Check whether the handshake is completed. */
645  if (SSL_is_init_finished(c->ssl) != TLS_ST_OK)
646  goto end;
647 
648  ret = 0;
649 end:
650  return ret;
651 }
652 
654 {
655  int ret;
656  TLSContext *c = h->priv_data;
657  TLSShared *s = &c->tls_shared;
658  EVP_PKEY *pkey = NULL;
659  X509 *cert = NULL;
660  /* setup ca, private key, certificate */
661  if (s->ca_file) {
662  if (!SSL_CTX_load_verify_locations(c->ctx, s->ca_file, NULL))
663  av_log(h, AV_LOG_ERROR, "SSL_CTX_load_verify_locations %s\n", openssl_get_error(c));
664  } else {
665  if (!SSL_CTX_set_default_verify_paths(c->ctx)) {
666  // Only log the failure but do not error out, as this is not fatal
667  av_log(h, AV_LOG_WARNING, "Failure setting default verify locations: %s\n",
669  }
670  }
671 
672  if (s->cert_file) {
673  ret = SSL_CTX_use_certificate_chain_file(c->ctx, s->cert_file);
674  if (ret <= 0) {
675  av_log(h, AV_LOG_ERROR, "Unable to load cert file %s: %s\n",
676  s->cert_file, openssl_get_error(c));
677  ret = AVERROR(EIO);
678  goto fail;
679  }
680  } else if (s->cert_buf) {
681  cert = cert_from_pem_string(s->cert_buf);
682  if (SSL_CTX_use_certificate(c->ctx, cert) != 1) {
683  av_log(c, AV_LOG_ERROR, "SSL: Init SSL_CTX_use_certificate failed, %s\n", openssl_get_error(c));
684  ret = AVERROR(EINVAL);
685  goto fail;
686  }
687  }
688 
689  if (s->key_file) {
690  ret = SSL_CTX_use_PrivateKey_file(c->ctx, s->key_file, SSL_FILETYPE_PEM);
691  if (ret <= 0) {
692  av_log(h, AV_LOG_ERROR, "Unable to load key file %s: %s\n",
693  s->key_file, openssl_get_error(c));
694  ret = AVERROR(EIO);
695  goto fail;
696  }
697  } else if (s->key_buf) {
698  pkey = pkey_from_pem_string(s->key_buf, 1);
699  if (SSL_CTX_use_PrivateKey(c->ctx, pkey) != 1) {
700  av_log(c, AV_LOG_ERROR, "Init SSL_CTX_use_PrivateKey failed, %s\n", openssl_get_error(c));
701  ret = AVERROR(EINVAL);
702  goto fail;
703  }
704  }
705 
706  if (s->listen && !s->cert_file && !s->cert_buf && !s->key_file && !s->key_buf) {
707  av_log(h, AV_LOG_VERBOSE, "No server certificate provided, using self-signed\n");
708 
709  ret = openssl_gen_private_key(&pkey);
710  if (ret < 0)
711  goto fail;
712 
713  ret = openssl_gen_certificate(pkey, &cert, NULL);
714  if (ret < 0)
715  goto fail;
716 
717  if (SSL_CTX_use_certificate(c->ctx, cert) != 1) {
718  av_log(c, AV_LOG_ERROR, "SSL_CTX_use_certificate failed for self-signed cert, %s\n", openssl_get_error(c));
719  ret = AVERROR(EINVAL);
720  goto fail;
721  }
722 
723  if (SSL_CTX_use_PrivateKey(c->ctx, pkey) != 1) {
724  av_log(c, AV_LOG_ERROR, "SSL_CTX_use_PrivateKey failed for self-signed cert, %s\n", openssl_get_error(c));
725  ret = AVERROR(EINVAL);
726  goto fail;
727  }
728  }
729 
730  ret = 0;
731 fail:
732  X509_free(cert);
733  EVP_PKEY_free(pkey);
734  return ret;
735 }
736 
737 /**
738  * Once the DTLS role has been negotiated - active for the DTLS client or passive for the
739  * DTLS server - we proceed to set up the DTLS state and initiate the handshake.
740  */
741 static int dtls_start(URLContext *h, const char *url, int flags, AVDictionary **options)
742 {
743  TLSContext *c = h->priv_data;
744  TLSShared *s = &c->tls_shared;
745  int ret = 0;
746  s->is_dtls = 1;
747 
748  if (!c->tls_shared.external_sock) {
749  if ((ret = ff_tls_open_underlying(&c->tls_shared, h, url, options)) < 0) {
750  av_log(c, AV_LOG_ERROR, "Failed to connect %s\n", url);
751  return ret;
752  }
753  }
754 
755  c->ctx = SSL_CTX_new(s->listen ? DTLS_server_method() : DTLS_client_method());
756  if (!c->ctx) {
757  ret = AVERROR(ENOMEM);
758  goto fail;
759  }
760 
762  if (ret < 0) goto fail;
763 
764  /* Note, this doesn't check that the peer certificate actually matches the requested hostname. */
765  if (s->verify)
766  SSL_CTX_set_verify(c->ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
767 
768  if (s->use_srtp) {
769  /**
770  * The profile for OpenSSL's SRTP is SRTP_AES128_CM_SHA1_80, see ssl/d1_srtp.c.
771  * The profile for FFmpeg's SRTP is SRTP_AES128_CM_HMAC_SHA1_80, see libavformat/srtp.c.
772  */
773  const char* profiles = "SRTP_AES128_CM_SHA1_80";
774  if (SSL_CTX_set_tlsext_use_srtp(c->ctx, profiles)) {
775  av_log(c, AV_LOG_ERROR, "Init SSL_CTX_set_tlsext_use_srtp failed, profiles=%s, %s\n",
777  ret = AVERROR(EINVAL);
778  goto fail;
779  }
780  }
781 
782  /* The ssl should not be created unless the ctx has been initialized. */
783  c->ssl = SSL_new(c->ctx);
784  if (!c->ssl) {
785  ret = AVERROR(ENOMEM);
786  goto fail;
787  }
788 
789  if (!s->listen && !s->numerichost)
790  SSL_set_tlsext_host_name(c->ssl, s->host);
791 
792  /* Setup the callback for logging. */
793  SSL_set_ex_data(c->ssl, 0, c);
794  SSL_CTX_set_info_callback(c->ctx, openssl_info_callback);
795 
796  /**
797  * We have set the MTU to fragment the DTLS packet. It is important to note that the
798  * packet is split to ensure that each handshake packet is smaller than the MTU.
799  */
800  if (s->mtu <= 0)
801  s->mtu = 1096;
802  SSL_set_options(c->ssl, SSL_OP_NO_QUERY_MTU);
803  SSL_set_mtu(c->ssl, s->mtu);
804  DTLS_set_link_mtu(c->ssl, s->mtu);
806 
807  /* This seems to be necessary despite explicitly setting client/server method above. */
808  if (s->listen)
809  SSL_set_accept_state(c->ssl);
810  else
811  SSL_set_connect_state(c->ssl);
812 
813  /* The SSL_do_handshake can't be called if DTLS hasn't prepare for udp. */
814  if (!c->tls_shared.external_sock) {
815  ret = dtls_handshake(h);
816  // Fatal SSL error, for example, no available suite when peer is DTLS 1.0 while we are DTLS 1.2.
817  if (ret < 0) {
818  av_log(c, AV_LOG_ERROR, "Failed to drive SSL context, ret=%d\n", ret);
819  return AVERROR(EIO);
820  }
821  }
822 
823  av_log(c, AV_LOG_VERBOSE, "Setup ok, MTU=%d\n", c->tls_shared.mtu);
824 
825  return 0;
826 fail:
827  tls_close(h);
828  return ret;
829 }
830 
831 static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
832 {
833  TLSContext *c = h->priv_data;
834  TLSShared *s = &c->tls_shared;
835  int ret;
836 
837  if ((ret = ff_tls_open_underlying(s, h, uri, options)) < 0)
838  goto fail;
839 
840  // We want to support all versions of TLS >= 1.0, but not the deprecated
841  // and insecure SSLv2 and SSLv3. Despite the name, TLS_*_method()
842  // enables support for all versions of SSL and TLS, and we then disable
843  // support for the old protocols immediately after creating the context.
844  c->ctx = SSL_CTX_new(s->listen ? TLS_server_method() : TLS_client_method());
845  if (!c->ctx) {
847  ret = AVERROR(EIO);
848  goto fail;
849  }
850  if (!SSL_CTX_set_min_proto_version(c->ctx, TLS1_VERSION)) {
851  av_log(h, AV_LOG_ERROR, "Failed to set minimum TLS version to TLSv1\n");
853  goto fail;
854  }
856  if (ret < 0) goto fail;
857 
858  if (s->verify)
859  SSL_CTX_set_verify(c->ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
860  c->ssl = SSL_new(c->ctx);
861  if (!c->ssl) {
863  ret = AVERROR(EIO);
864  goto fail;
865  }
866  SSL_set_ex_data(c->ssl, 0, c);
867  SSL_CTX_set_info_callback(c->ctx, openssl_info_callback);
869  if (!s->listen && !s->numerichost) {
870  // By default OpenSSL does too lax wildcard matching
871  SSL_set_hostflags(c->ssl, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
872  if (!SSL_set1_host(c->ssl, s->host)) {
873  av_log(h, AV_LOG_ERROR, "Failed to set hostname for TLS/SSL verification: %s\n",
876  goto fail;
877  }
878  if (!SSL_set_tlsext_host_name(c->ssl, s->host)) {
879  av_log(h, AV_LOG_ERROR, "Failed to set hostname for SNI: %s\n", openssl_get_error(c));
881  goto fail;
882  }
883  }
884  ret = s->listen ? SSL_accept(c->ssl) : SSL_connect(c->ssl);
885  if (ret == 0) {
886  av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n");
887  ret = AVERROR(EIO);
888  goto fail;
889  } else if (ret < 0) {
890  ret = print_ssl_error(h, ret);
891  goto fail;
892  }
893 
894  return 0;
895 fail:
896  tls_close(h);
897  return ret;
898 }
899 
900 static int tls_read(URLContext *h, uint8_t *buf, int size)
901 {
902  TLSContext *c = h->priv_data;
903  TLSShared *s = &c->tls_shared;
904  URLContext *uc = s->is_dtls ? s->udp : s->tcp;
905  int ret;
906  // Set or clear the AVIO_FLAG_NONBLOCK on the underlying socket
907  uc->flags &= ~AVIO_FLAG_NONBLOCK;
908  uc->flags |= h->flags & AVIO_FLAG_NONBLOCK;
909  ret = SSL_read(c->ssl, buf, size);
910  if (ret > 0)
911  return ret;
912  if (ret == 0)
913  return AVERROR_EOF;
914  return print_ssl_error(h, ret);
915 }
916 
917 static int tls_write(URLContext *h, const uint8_t *buf, int size)
918 {
919  TLSContext *c = h->priv_data;
920  TLSShared *s = &c->tls_shared;
921  URLContext *uc = s->is_dtls ? s->udp : s->tcp;
922  int ret;
923 
924  // Set or clear the AVIO_FLAG_NONBLOCK on the underlying socket
925  uc->flags &= ~AVIO_FLAG_NONBLOCK;
926  uc->flags |= h->flags & AVIO_FLAG_NONBLOCK;
927 
928  if (s->is_dtls) {
929  const size_t mtu_size = DTLS_get_data_mtu(c->ssl);
930  size = FFMIN(size, mtu_size);
931  }
932 
933  ret = SSL_write(c->ssl, buf, size);
934  if (ret > 0)
935  return ret;
936  if (ret == 0)
937  return AVERROR_EOF;
938  return print_ssl_error(h, ret);
939 }
940 
942 {
943  TLSContext *c = h->priv_data;
944  TLSShared *s = &c->tls_shared;
945  return ffurl_get_file_handle(s->is_dtls ? s->udp : s->tcp);
946 }
947 
949 {
950  TLSContext *c = h->priv_data;
951  TLSShared *s = &c->tls_shared;
952  return ffurl_get_short_seek(s->is_dtls ? s->udp : s->tcp);
953 }
954 
955 static const AVOption options[] = {
956  TLS_COMMON_OPTIONS(TLSContext, tls_shared),
957  { NULL }
958 };
959 
960 static const AVClass tls_class = {
961  .class_name = "tls",
962  .item_name = av_default_item_name,
963  .option = options,
964  .version = LIBAVUTIL_VERSION_INT,
965 };
966 
968  .name = "tls",
969  .url_open2 = tls_open,
970  .url_read = tls_read,
971  .url_write = tls_write,
972  .url_close = tls_close,
973  .url_get_file_handle = tls_get_file_handle,
974  .url_get_short_seek = tls_get_short_seek,
975  .priv_data_size = sizeof(TLSContext),
977  .priv_data_class = &tls_class,
978 };
979 
980 static const AVClass dtls_class = {
981  .class_name = "dtls",
982  .item_name = av_default_item_name,
983  .option = options,
984  .version = LIBAVUTIL_VERSION_INT,
985 };
986 
988  .name = "dtls",
989  .url_open2 = dtls_start,
990  .url_handshake = dtls_handshake,
991  .url_close = tls_close,
992  .url_read = tls_read,
993  .url_write = tls_write,
994  .url_get_file_handle = tls_get_file_handle,
995  .url_get_short_seek = tls_get_short_seek,
996  .priv_data_size = sizeof(TLSContext),
998  .priv_data_class = &dtls_class,
999 };
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:435
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:460
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:960
fail
#define fail()
Definition: checkasm.h:219
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:515
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:917
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:967
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:624
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:574
url_bio_destroy
static int url_bio_destroy(BIO *b)
Definition: tls_openssl.c:523
ff_tls_set_external_socket
int ff_tls_set_external_socket(URLContext *h, URLContext *sock)
Definition: tls_openssl.c:447
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:558
tls_open
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
Definition: tls_openssl.c:831
TLSContext::error_message
char error_message[256]
Definition: tls_openssl.c:423
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:528
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:419
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:955
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:605
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:941
init_bio_method
static av_cold void init_bio_method(URLContext *h)
Definition: tls_openssl.c:588
TLSContext::ssl
SSL * ssl
Definition: tls_openssl.c:420
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:475
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:948
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:900
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:653
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:741
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:980
tls_close
static int tls_close(URLContext *h)
Definition: tls_openssl.c:499
ff_dtls_protocol
const URLProtocol ff_dtls_protocol
Definition: tls_openssl.c:987
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:421
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:583
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