FFmpeg
tls_openssl.c
Go to the documentation of this file.
1 /*
2  * TLS/SSL Protocol
3  * Copyright (c) 2011 Martin Storsjo
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "avformat.h"
23 #include "internal.h"
24 #include "network.h"
25 #include "os_support.h"
26 #include "url.h"
27 #include "tls.h"
28 #include "libavcodec/internal.h"
29 #include "libavutil/avstring.h"
30 #include "libavutil/avutil.h"
31 #include "libavutil/opt.h"
32 #include "libavutil/parseutils.h"
33 #include "libavutil/thread.h"
34 
35 #include <openssl/bio.h>
36 #include <openssl/ssl.h>
37 #include <openssl/err.h>
38 
39 static int openssl_init;
40 
41 typedef struct TLSContext {
42  const AVClass *class;
44  SSL_CTX *ctx;
45  SSL *ssl;
46 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
47  BIO_METHOD* url_bio_method;
48 #endif
49 } TLSContext;
50 
51 #if HAVE_THREADS
52 #include <openssl/crypto.h>
53 pthread_mutex_t *openssl_mutexes;
54 static void openssl_lock(int mode, int type, const char *file, int line)
55 {
56  if (mode & CRYPTO_LOCK)
57  pthread_mutex_lock(&openssl_mutexes[type]);
58  else
59  pthread_mutex_unlock(&openssl_mutexes[type]);
60 }
61 #if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000
62 static unsigned long openssl_thread_id(void)
63 {
64  return (intptr_t) pthread_self();
65 }
66 #endif
67 #endif
68 
69 int ff_openssl_init(void)
70 {
72  if (!openssl_init) {
73  SSL_library_init();
74  SSL_load_error_strings();
75 #if HAVE_THREADS
76  if (!CRYPTO_get_locking_callback()) {
77  int i;
78  openssl_mutexes = av_malloc_array(sizeof(pthread_mutex_t), CRYPTO_num_locks());
79  if (!openssl_mutexes) {
81  return AVERROR(ENOMEM);
82  }
83 
84  for (i = 0; i < CRYPTO_num_locks(); i++)
85  pthread_mutex_init(&openssl_mutexes[i], NULL);
86  CRYPTO_set_locking_callback(openssl_lock);
87 #if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000
88  CRYPTO_set_id_callback(openssl_thread_id);
89 #endif
90  }
91 #endif
92  }
93  openssl_init++;
95 
96  return 0;
97 }
98 
100 {
102  openssl_init--;
103  if (!openssl_init) {
104 #if HAVE_THREADS
105  if (CRYPTO_get_locking_callback() == openssl_lock) {
106  int i;
107  CRYPTO_set_locking_callback(NULL);
108  for (i = 0; i < CRYPTO_num_locks(); i++)
109  pthread_mutex_destroy(&openssl_mutexes[i]);
110  av_free(openssl_mutexes);
111  }
112 #endif
113  }
115 }
116 
117 static int print_tls_error(URLContext *h, int ret)
118 {
119  TLSContext *c = h->priv_data;
120  if (h->flags & AVIO_FLAG_NONBLOCK) {
121  int err = SSL_get_error(c->ssl, ret);
122  if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
123  return AVERROR(EAGAIN);
124  }
125  av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
126  return AVERROR(EIO);
127 }
128 
129 static int tls_close(URLContext *h)
130 {
131  TLSContext *c = h->priv_data;
132  if (c->ssl) {
133  SSL_shutdown(c->ssl);
134  SSL_free(c->ssl);
135  }
136  if (c->ctx)
137  SSL_CTX_free(c->ctx);
138  if (c->tls_shared.tcp)
139  ffurl_close(c->tls_shared.tcp);
140 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
141  if (c->url_bio_method)
142  BIO_meth_free(c->url_bio_method);
143 #endif
145  return 0;
146 }
147 
148 static int url_bio_create(BIO *b)
149 {
150 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
151  BIO_set_init(b, 1);
152  BIO_set_data(b, NULL);
153  BIO_set_flags(b, 0);
154 #else
155  b->init = 1;
156  b->ptr = NULL;
157  b->flags = 0;
158 #endif
159  return 1;
160 }
161 
162 static int url_bio_destroy(BIO *b)
163 {
164  return 1;
165 }
166 
167 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
168 #define GET_BIO_DATA(x) BIO_get_data(x)
169 #else
170 #define GET_BIO_DATA(x) (x)->ptr
171 #endif
172 
173 static int url_bio_bread(BIO *b, char *buf, int len)
174 {
176  int ret = ffurl_read(h, buf, len);
177  if (ret >= 0)
178  return ret;
179  BIO_clear_retry_flags(b);
180  if (ret == AVERROR(EAGAIN))
181  BIO_set_retry_read(b);
182  if (ret == AVERROR_EXIT)
183  return 0;
184  return -1;
185 }
186 
187 static int url_bio_bwrite(BIO *b, const char *buf, int len)
188 {
190  int ret = ffurl_write(h, buf, len);
191  if (ret >= 0)
192  return ret;
193  BIO_clear_retry_flags(b);
194  if (ret == AVERROR(EAGAIN))
195  BIO_set_retry_write(b);
196  if (ret == AVERROR_EXIT)
197  return 0;
198  return -1;
199 }
200 
201 static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
202 {
203  if (cmd == BIO_CTRL_FLUSH) {
204  BIO_clear_retry_flags(b);
205  return 1;
206  }
207  return 0;
208 }
209 
210 static int url_bio_bputs(BIO *b, const char *str)
211 {
212  return url_bio_bwrite(b, str, strlen(str));
213 }
214 
215 #if OPENSSL_VERSION_NUMBER < 0x1010000fL
216 static BIO_METHOD url_bio_method = {
217  .type = BIO_TYPE_SOURCE_SINK,
218  .name = "urlprotocol bio",
219  .bwrite = url_bio_bwrite,
220  .bread = url_bio_bread,
221  .bputs = url_bio_bputs,
222  .bgets = NULL,
223  .ctrl = url_bio_ctrl,
224  .create = url_bio_create,
225  .destroy = url_bio_destroy,
226 };
227 #endif
228 
229 static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
230 {
231  TLSContext *p = h->priv_data;
232  TLSShared *c = &p->tls_shared;
233  BIO *bio;
234  int ret;
235 
236  if ((ret = ff_openssl_init()) < 0)
237  return ret;
238 
239  if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0)
240  goto fail;
241 
242  // We want to support all versions of TLS >= 1.0, but not the deprecated
243  // and insecure SSLv2 and SSLv3. Despite the name, SSLv23_*_method()
244  // enables support for all versions of SSL and TLS, and we then disable
245  // support for the old protocols immediately after creating the context.
246  p->ctx = SSL_CTX_new(c->listen ? SSLv23_server_method() : SSLv23_client_method());
247  if (!p->ctx) {
248  av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
249  ret = AVERROR(EIO);
250  goto fail;
251  }
252  SSL_CTX_set_options(p->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
253  if (c->ca_file) {
254  if (!SSL_CTX_load_verify_locations(p->ctx, c->ca_file, NULL))
255  av_log(h, AV_LOG_ERROR, "SSL_CTX_load_verify_locations %s\n", ERR_error_string(ERR_get_error(), NULL));
256  }
257  if (c->cert_file && !SSL_CTX_use_certificate_chain_file(p->ctx, c->cert_file)) {
258  av_log(h, AV_LOG_ERROR, "Unable to load cert file %s: %s\n",
259  c->cert_file, ERR_error_string(ERR_get_error(), NULL));
260  ret = AVERROR(EIO);
261  goto fail;
262  }
263  if (c->key_file && !SSL_CTX_use_PrivateKey_file(p->ctx, c->key_file, SSL_FILETYPE_PEM)) {
264  av_log(h, AV_LOG_ERROR, "Unable to load key file %s: %s\n",
265  c->key_file, ERR_error_string(ERR_get_error(), NULL));
266  ret = AVERROR(EIO);
267  goto fail;
268  }
269  // Note, this doesn't check that the peer certificate actually matches
270  // the requested hostname.
271  if (c->verify)
272  SSL_CTX_set_verify(p->ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
273  p->ssl = SSL_new(p->ctx);
274  if (!p->ssl) {
275  av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
276  ret = AVERROR(EIO);
277  goto fail;
278  }
279 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
280  p->url_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "urlprotocol bio");
281  BIO_meth_set_write(p->url_bio_method, url_bio_bwrite);
282  BIO_meth_set_read(p->url_bio_method, url_bio_bread);
283  BIO_meth_set_puts(p->url_bio_method, url_bio_bputs);
284  BIO_meth_set_ctrl(p->url_bio_method, url_bio_ctrl);
285  BIO_meth_set_create(p->url_bio_method, url_bio_create);
286  BIO_meth_set_destroy(p->url_bio_method, url_bio_destroy);
287  bio = BIO_new(p->url_bio_method);
288  BIO_set_data(bio, c->tcp);
289 #else
290  bio = BIO_new(&url_bio_method);
291  bio->ptr = c->tcp;
292 #endif
293  SSL_set_bio(p->ssl, bio, bio);
294  if (!c->listen && !c->numerichost)
295  SSL_set_tlsext_host_name(p->ssl, c->host);
296  ret = c->listen ? SSL_accept(p->ssl) : SSL_connect(p->ssl);
297  if (ret == 0) {
298  av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n");
299  ret = AVERROR(EIO);
300  goto fail;
301  } else if (ret < 0) {
302  ret = print_tls_error(h, ret);
303  goto fail;
304  }
305 
306  return 0;
307 fail:
308  tls_close(h);
309  return ret;
310 }
311 
312 static int tls_read(URLContext *h, uint8_t *buf, int size)
313 {
314  TLSContext *c = h->priv_data;
315  int ret;
316  // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
317  c->tls_shared.tcp->flags &= ~AVIO_FLAG_NONBLOCK;
318  c->tls_shared.tcp->flags |= h->flags & AVIO_FLAG_NONBLOCK;
319  ret = SSL_read(c->ssl, buf, size);
320  if (ret > 0)
321  return ret;
322  if (ret == 0)
323  return AVERROR_EOF;
324  return print_tls_error(h, ret);
325 }
326 
327 static int tls_write(URLContext *h, const uint8_t *buf, int size)
328 {
329  TLSContext *c = h->priv_data;
330  int ret;
331  // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
332  c->tls_shared.tcp->flags &= ~AVIO_FLAG_NONBLOCK;
333  c->tls_shared.tcp->flags |= h->flags & AVIO_FLAG_NONBLOCK;
334  ret = SSL_write(c->ssl, buf, size);
335  if (ret > 0)
336  return ret;
337  if (ret == 0)
338  return AVERROR_EOF;
339  return print_tls_error(h, ret);
340 }
341 
343 {
344  TLSContext *c = h->priv_data;
345  return ffurl_get_file_handle(c->tls_shared.tcp);
346 }
347 
348 static const AVOption options[] = {
349  TLS_COMMON_OPTIONS(TLSContext, tls_shared),
350  { NULL }
351 };
352 
353 static const AVClass tls_class = {
354  .class_name = "tls",
355  .item_name = av_default_item_name,
356  .option = options,
357  .version = LIBAVUTIL_VERSION_INT,
358 };
359 
361  .name = "tls",
362  .url_open2 = tls_open,
363  .url_read = tls_read,
364  .url_write = tls_write,
365  .url_close = tls_close,
366  .url_get_file_handle = tls_get_file_handle,
367  .priv_data_size = sizeof(TLSContext),
369  .priv_data_class = &tls_class,
370 };
pthread_mutex_t
_fmutex pthread_mutex_t
Definition: os2threads.h:49
TLSContext
Definition: tls_gnutls.c:48
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:34
thread.h
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:55
pthread_mutex_init
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:100
internal.h
AVOption
AVOption.
Definition: opt.h:246
b
#define b
Definition: input.c:41
ffurl_close
int ffurl_close(URLContext *h)
Definition: avio.c:470
AVDictionary
Definition: dict.c:30
URLProtocol
Definition: url.h:54
os_support.h
ff_openssl_deinit
void ff_openssl_deinit(void)
Definition: tls_openssl.c:99
ff_unlock_avformat
int ff_unlock_avformat(void)
Definition: utils.c:88
TLS_COMMON_OPTIONS
#define TLS_COMMON_OPTIONS(pstruct, options_field)
Definition: tls.h:45
tls_class
static const AVClass tls_class
Definition: tls_openssl.c:353
fail
#define fail()
Definition: checkasm.h:120
url_bio_create
static int url_bio_create(BIO *b)
Definition: tls_openssl.c:148
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
GET_BIO_DATA
#define GET_BIO_DATA(x)
Definition: tls_openssl.c:170
openssl_init
static int openssl_init
Definition: tls_openssl.c:39
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
buf
void * buf
Definition: avisynth_c.h:766
tls_write
static int tls_write(URLContext *h, const uint8_t *buf, int size)
Definition: tls_openssl.c:327
ff_tls_protocol
const URLProtocol ff_tls_protocol
Definition: tls_openssl.c:360
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
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:191
parseutils.h
url_bio_ctrl
static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
Definition: tls_openssl.c:201
ff_openssl_init
int ff_openssl_init(void)
Definition: tls_openssl.c:69
url_bio_destroy
static int url_bio_destroy(BIO *b)
Definition: tls_openssl.c:162
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:187
tls_open
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
Definition: tls_openssl.c:229
pthread_mutex_unlock
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:65
url_bio_bread
static int url_bio_bread(BIO *b, char *buf, int len)
Definition: tls_openssl.c:173
TLSContext::ctx
SSL_CTX * ctx
Definition: tls_openssl.c:44
size
int size
Definition: twinvq_data.h:11134
TLSContext::tls_shared
TLSShared tls_shared
Definition: tls_gnutls.c:50
URLProtocol::name
const char * name
Definition: url.h:55
ff_lock_avformat
int ff_lock_avformat(void)
Definition: utils.c:83
options
static const AVOption options[]
Definition: tls_openssl.c:348
line
Definition: graph2dot.c:48
tls_get_file_handle
static int tls_get_file_handle(URLContext *h)
Definition: tls_openssl.c:342
pthread_mutex_destroy
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:108
TLSContext::ssl
SSL * ssl
Definition: tls_openssl.c:45
URLContext
Definition: url.h:38
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
url.h
uint8_t
uint8_t
Definition: audio_convert.c:194
print_tls_error
static int print_tls_error(URLContext *h, int ret)
Definition: tls_openssl.c:117
len
int len
Definition: vorbis_enc_data.h:452
ff_tls_open_underlying
int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AVDictionary **options)
Definition: tls.c:56
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:72
avformat.h
network.h
tls.h
ffurl_read
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:410
mode
mode
Definition: ebur128.h:83
ffurl_write
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:424
tls_read
static int tls_read(URLContext *h, uint8_t *buf, int size)
Definition: tls_openssl.c:312
avutil.h
url_bio_method
static BIO_METHOD url_bio_method
Definition: tls_openssl.c:216
TLSShared
Definition: tls.h:29
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVIO_FLAG_NONBLOCK
#define AVIO_FLAG_NONBLOCK
Use non-blocking mode.
Definition: avio.h:673
TLSContext::ctx
struct tls * ctx
Definition: tls_libtls.c:37
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
h
h
Definition: vp9dsp_template.c:2038
AVERROR_EXIT
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:56
avstring.h
tls_close
static int tls_close(URLContext *h)
Definition: tls_openssl.c:129
ffurl_get_file_handle
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
Definition: avio.c:629
url_bio_bputs
static int url_bio_bputs(BIO *b, const char *str)
Definition: tls_openssl.c:210
pthread_mutex_lock
#define pthread_mutex_lock(a)
Definition: ffprobe.c:61