FFmpeg
Loading...
Searching...
No Matches
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"
26#include "network.h"
27#include "url.h"
28#include "tls.h"
29#include "libavcodec/internal.h"
30#include "libavutil/avutil.h"
31#include "libavutil/opt.h"
32
33#include <tls.h>
34
35typedef struct TLSContext {
36 TLSShared tls_shared;
37 struct tls *ctx;
39
41{
42 TLSContext *p = h->priv_data;
43 if (p->ctx) {
44 tls_close(p->ctx);
45 tls_free(p->ctx);
46 }
47 ffurl_closep(&p->tls_shared.tcp);
48 return 0;
49}
50
51static 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
62static 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
73static 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;
137err_config:
138 av_log(h, AV_LOG_ERROR, "%s\n", tls_config_error(cfg));
139 ret = AVERROR(EIO);
140 goto fail;
141err_ctx:
142 av_log(h, AV_LOG_ERROR, "%s\n", tls_error(p->ctx));
143 ret = AVERROR(EIO);
145fail:
146 if (cfg)
147 tls_config_free(cfg);
149 return ret;
150}
151
152static 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 else if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT)
162 return AVERROR(EAGAIN);
163 av_log(h, AV_LOG_ERROR, "%s\n", tls_error(p->ctx));
164 return AVERROR(EIO);
165}
166
167static int ff_tls_write(URLContext *h, const uint8_t *buf, int size)
168{
169 TLSContext *p = h->priv_data;
170 ssize_t ret;
171 ret = tls_write(p->ctx, buf, size);
172 if (ret > 0)
173 return ret;
174 else if (ret == 0)
175 return AVERROR_EOF;
176 else if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT)
177 return AVERROR(EAGAIN);
178 av_log(h, AV_LOG_ERROR, "%s\n", tls_error(p->ctx));
179 return AVERROR(EIO);
180}
181
183{
184 TLSContext *c = h->priv_data;
185 return ffurl_get_file_handle(c->tls_shared.tcp);
186}
187
189{
190 TLSContext *s = h->priv_data;
191 return ffurl_get_short_seek(s->tls_shared.tcp);
192}
193
194static const AVOption options[] = {
195 TLS_COMMON_OPTIONS(TLSContext, tls_shared),
196 { NULL }
197};
198
199static const AVClass tls_class = {
200 .class_name = "tls",
201 .item_name = av_default_item_name,
202 .option = options,
203 .version = LIBAVUTIL_VERSION_INT,
204};
205
207 .name = "tls",
208 .url_open2 = ff_tls_open,
209 .url_read = ff_tls_read,
210 .url_write = ff_tls_write,
211 .url_close = ff_tls_close,
212 .url_get_file_handle = tls_get_file_handle,
213 .url_get_short_seek = tls_get_short_seek,
214 .priv_data_size = sizeof(TLSContext),
216 .priv_data_class = &tls_class,
217};
static AVFormatContext * ctx
Main libavformat public API header.
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
Definition avio.c:656
int ffurl_get_short_seek(void *urlcontext)
Return the current short seek threshold value for this URL.
Definition avio.c:906
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
Definition avio.c:882
Convenience header that includes libavutil's core.
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
static CheckasmConfig cfg
Definition checkasm.c:74
#define fail
Definition test.h:479
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition error.h:58
#define AVERROR_EOF
End of file.
Definition error.h:57
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
common internal api header.
Macro definitions for various function/variable attributes.
#define av_fallthrough
Definition attributes.h:67
AVOptions.
const URLProtocol ff_tls_protocol
Definition tls_gnutls.c:771
Describe the class of an AVClass context structure.
Definition log.h:76
AVOption.
Definition opt.h:428
struct tls * ctx
Definition tls_libtls.c:37
TLSShared tls_shared
Definition tls_gnutls.c:337
#define av_log(a,...)
int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AVDictionary **options)
Definition tls.c:54
#define TLS_COMMON_OPTIONS(pstruct, options_field)
Definition tls.h:101
static int tls_close(URLContext *h)
Definition tls_gnutls.c:419
static const AVClass tls_class
Definition tls_gnutls.c:764
static int tls_read(URLContext *h, uint8_t *buf, int size)
Definition tls_gnutls.c:707
static int tls_get_short_seek(URLContext *h)
Definition tls_gnutls.c:753
static int tls_write(URLContext *h, const uint8_t *buf, int size)
Definition tls_gnutls.c:724
static int tls_get_file_handle(URLContext *h)
Definition tls_gnutls.c:747
static int ff_tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
Definition tls_libtls.c:73
static ssize_t tls_write_callback(struct tls *ctx, const void *buf, size_t buflen, void *cb_arg)
Definition tls_libtls.c:62
static int ff_tls_close(URLContext *h)
Definition tls_libtls.c:40
static int tls_get_short_seek(URLContext *h)
Definition tls_libtls.c:188
static int ff_tls_read(URLContext *h, uint8_t *buf, int size)
Definition tls_libtls.c:152
static int tls_get_file_handle(URLContext *h)
Definition tls_libtls.c:182
static int ff_tls_write(URLContext *h, const uint8_t *buf, int size)
Definition tls_libtls.c:167
static ssize_t tls_read_callback(struct tls *ctx, void *buf, size_t buflen, void *cb_arg)
Definition tls_libtls.c:51
int size
unbuffered private I/O API
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:204
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:183
#define URL_PROTOCOL_FLAG_NETWORK
Definition url.h:33
static double c[64]