FFmpeg  4.3.9
tls_libtls.c
Go to the documentation of this file.
1 /*
2  * TLS/SSL Protocol
3  * Copyright (c) 2011 Martin Storsjo
4  * Copyright (c) 2017 sfan5 <sfan5@live.de>
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 "avformat.h"
24 #include "internal.h"
25 #include "network.h"
26 #include "url.h"
27 #include "tls.h"
28 #include "libavcodec/internal.h"
29 #include "libavutil/avutil.h"
30 #include "libavutil/opt.h"
31 
32 #include <tls.h>
33 
34 typedef struct TLSContext {
35  const AVClass *class;
37  struct tls *ctx;
38 } TLSContext;
39 
41 {
42  TLSContext *p = h->priv_data;
43  if (p->ctx) {
44  tls_close(p->ctx);
45  tls_free(p->ctx);
46  }
48  return 0;
49 }
50 
51 static ssize_t tls_read_callback(struct tls *ctx, void *buf, size_t buflen, void *cb_arg)
52 {
53  URLContext *h = (URLContext*) cb_arg;
54  int ret = ffurl_read(h, buf, buflen);
55  if (ret == AVERROR(EAGAIN))
56  return TLS_WANT_POLLIN;
57  else if (ret == AVERROR_EXIT)
58  return 0;
59  return ret >= 0 ? ret : -1;
60 }
61 
62 static ssize_t tls_write_callback(struct tls *ctx, const void *buf, size_t buflen, void *cb_arg)
63 {
64  URLContext *h = (URLContext*) cb_arg;
65  int ret = ffurl_write(h, buf, buflen);
66  if (ret == AVERROR(EAGAIN))
67  return TLS_WANT_POLLOUT;
68  else if (ret == AVERROR_EXIT)
69  return 0;
70  return ret >= 0 ? ret : -1;
71 }
72 
73 static int ff_tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
74 {
75  TLSContext *p = h->priv_data;
76  TLSShared *c = &p->tls_shared;
77  struct tls_config *cfg = NULL;
78  int ret;
79 
80  if (tls_init() == -1) {
81  ret = AVERROR(EIO);
82  goto fail;
83  }
84 
85  if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0)
86  goto fail;
87 
88  p->ctx = !c->listen ? tls_client() : tls_server();
89  if (!p->ctx) {
90  ret = AVERROR(EIO);
91  goto fail;
92  }
93 
94  cfg = tls_config_new();
95  if (!p->ctx) {
96  ret = AVERROR(EIO);
97  goto fail;
98  }
99  if (tls_config_set_protocols(cfg, TLS_PROTOCOLS_ALL) == -1)
100  goto err_config;
101  // While TLSv1.0 and TLSv1.1 are already enabled by the above,
102  // we need to be less strict with ciphers so it works in practice.
103  if (tls_config_set_ciphers(cfg, "compat") == -1)
104  goto err_config;
105  if (c->ca_file && tls_config_set_ca_file(cfg, c->ca_file) == -1)
106  goto err_config;
107  if (c->cert_file && tls_config_set_cert_file(cfg, c->cert_file) == -1)
108  goto err_config;
109  if (c->key_file && tls_config_set_key_file(cfg, c->key_file) == -1)
110  goto err_config;
111  if (!c->verify) {
112  tls_config_insecure_noverifycert(cfg);
113  tls_config_insecure_noverifyname(cfg);
114  tls_config_insecure_noverifytime(cfg);
115  }
116  if (tls_configure(p->ctx, cfg) == -1)
117  goto err_ctx;
118 
119  if (!c->listen) {
120  ret = tls_connect_cbs(p->ctx, tls_read_callback, tls_write_callback,
121  c->tcp, c->host);
122  } else {
123  struct tls *ctx_new;
124  ret = tls_accept_cbs(p->ctx, &ctx_new, tls_read_callback,
125  tls_write_callback, c->tcp);
126  if (ret == 0) {
127  // free "server" context and replace by "connection" context
128  tls_free(p->ctx);
129  p->ctx = ctx_new;
130  }
131  }
132  if (ret == -1)
133  goto err_ctx;
134 
135  tls_config_free(cfg);
136  return 0;
137 err_config:
138  av_log(h, AV_LOG_ERROR, "%s\n", tls_config_error(cfg));
139  ret = AVERROR(EIO);
140  goto fail;
141 err_ctx:
142  av_log(h, AV_LOG_ERROR, "%s\n", tls_error(p->ctx));
143  ret = AVERROR(EIO);
144  /* fallthrough */
145 fail:
146  if (cfg)
147  tls_config_free(cfg);
148  ff_tls_close(h);
149  return ret;
150 }
151 
152 static int ff_tls_read(URLContext *h, uint8_t *buf, int size)
153 {
154  TLSContext *p = h->priv_data;
155  ssize_t ret;
156  ret = tls_read(p->ctx, buf, size);
157  if (ret > 0)
158  return ret;
159  else if (ret == 0)
160  return AVERROR_EOF;
161  av_log(h, AV_LOG_ERROR, "%s\n", tls_error(p->ctx));
162  return AVERROR(EIO);
163 }
164 
165 static int ff_tls_write(URLContext *h, const uint8_t *buf, int size)
166 {
167  TLSContext *p = h->priv_data;
168  ssize_t ret;
169  ret = tls_write(p->ctx, buf, size);
170  if (ret > 0)
171  return ret;
172  else if (ret == 0)
173  return AVERROR_EOF;
174  av_log(h, AV_LOG_ERROR, "%s\n", tls_error(p->ctx));
175  return AVERROR(EIO);
176 }
177 
179 {
180  TLSContext *c = h->priv_data;
182 }
183 
184 static const AVOption options[] = {
186  { NULL }
187 };
188 
189 static const AVClass tls_class = {
190  .class_name = "tls",
191  .item_name = av_default_item_name,
192  .option = options,
193  .version = LIBAVUTIL_VERSION_INT,
194 };
195 
197  .name = "tls",
198  .url_open2 = ff_tls_open,
199  .url_read = ff_tls_read,
200  .url_write = ff_tls_write,
201  .url_close = ff_tls_close,
202  .url_get_file_handle = tls_get_file_handle,
203  .priv_data_size = sizeof(TLSContext),
205  .priv_data_class = &tls_class,
206 };
#define NULL
Definition: coverity.c:32
int size
#define URL_PROTOCOL_FLAG_NETWORK
Definition: url.h:34
AVOption.
Definition: opt.h:246
int verify
Definition: tls.h:31
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
int ffurl_write(URLContext *h, const unsigned char *buf, int size)
Write size bytes from buf to the resource accessed by h.
Definition: avio.c:423
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
Convenience header that includes libavutil&#39;s core.
int listen
Definition: tls.h:34
static int ff_tls_read(URLContext *h, uint8_t *buf, int size)
Definition: tls_libtls.c:152
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:72
uint8_t
AVOptions.
Definition: tls.h:29
static const AVOption options[]
Definition: tls_libtls.c:184
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define av_log(a,...)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AVERROR(e)
Definition: error.h:43
static int tls_read(URLContext *h, uint8_t *buf, int size)
Definition: tls_gnutls.c:236
#define fail()
Definition: checkasm.h:123
char * host
Definition: tls.h:36
static ssize_t tls_read_callback(struct tls *ctx, void *buf, size_t buflen, void *cb_arg)
Definition: tls_libtls.c:51
#define TLS_COMMON_OPTIONS(pstruct, options_field)
Definition: tls.h:45
static int tls_close(URLContext *h)
Definition: tls_gnutls.c:94
char * cert_file
Definition: tls.h:32
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
Definition: avio.c:628
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:56
char * ca_file
Definition: tls.h:30
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
Definition: avio.c:446
const URLProtocol ff_tls_protocol
Definition: tls_libtls.c:196
static int tls_get_file_handle(URLContext *h)
Definition: tls_libtls.c:178
TLSShared tls_shared
Definition: tls_gnutls.c:50
Definition: url.h:38
Describe the class of an AVClass context structure.
Definition: log.h:67
static int ff_tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
Definition: tls_libtls.c:73
void * priv_data
Definition: url.h:41
const char * name
Definition: url.h:55
#define flags(name, subs,...)
Definition: cbs_av1.c:576
static ssize_t tls_write_callback(struct tls *ctx, const void *buf, size_t buflen, void *cb_arg)
Definition: tls_libtls.c:62
Main libavformat public API header.
common internal api header.
int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AVDictionary **options)
Definition: tls.c:56
struct tls * ctx
Definition: tls_libtls.c:37
static double c[64]
URLContext * tcp
Definition: tls.h:41
static const AVClass tls_class
Definition: tls_libtls.c:189
static int ff_tls_write(URLContext *h, const uint8_t *buf, int size)
Definition: tls_libtls.c:165
static int tls_write(URLContext *h, const uint8_t *buf, int size)
Definition: tls_gnutls.c:251
unbuffered private I/O API
static int ff_tls_close(URLContext *h)
Definition: tls_libtls.c:40
int ffurl_read(URLContext *h, unsigned char *buf, int size)
Read up to size bytes from the resource accessed by h, and store the read bytes in buf...
Definition: avio.c:409
char * key_file
Definition: tls.h:33