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 "libavutil/avstring.h"
29 #include "libavutil/avutil.h"
30 #include "libavutil/mem.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  int io_err;
50 } TLSContext;
51 
52 #if HAVE_THREADS && OPENSSL_VERSION_NUMBER < 0x10100000L
53 #include <openssl/crypto.h>
54 pthread_mutex_t *openssl_mutexes;
55 static void openssl_lock(int mode, int type, const char *file, int line)
56 {
57  if (mode & CRYPTO_LOCK)
58  pthread_mutex_lock(&openssl_mutexes[type]);
59  else
60  pthread_mutex_unlock(&openssl_mutexes[type]);
61 }
62 #if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000
63 static unsigned long openssl_thread_id(void)
64 {
65  return (intptr_t) pthread_self();
66 }
67 #endif
68 #endif
69 
70 int ff_openssl_init(void)
71 {
73  if (!openssl_init) {
74  /* OpenSSL 1.0.2 or below, then you would use SSL_library_init. If you are
75  * using OpenSSL 1.1.0 or above, then the library will initialize
76  * itself automatically.
77  * https://wiki.openssl.org/index.php/Library_Initialization
78  */
79 #if OPENSSL_VERSION_NUMBER < 0x10100000L
80  SSL_library_init();
81  SSL_load_error_strings();
82 #endif
83 #if HAVE_THREADS && OPENSSL_VERSION_NUMBER < 0x10100000L
84  if (!CRYPTO_get_locking_callback()) {
85  int i;
86  openssl_mutexes = av_malloc_array(sizeof(pthread_mutex_t), CRYPTO_num_locks());
87  if (!openssl_mutexes) {
89  return AVERROR(ENOMEM);
90  }
91 
92  for (i = 0; i < CRYPTO_num_locks(); i++)
93  pthread_mutex_init(&openssl_mutexes[i], NULL);
94  CRYPTO_set_locking_callback(openssl_lock);
95 #if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000
96  CRYPTO_set_id_callback(openssl_thread_id);
97 #endif
98  }
99 #endif
100  }
101  openssl_init++;
103 
104  return 0;
105 }
106 
108 {
110  openssl_init--;
111  if (!openssl_init) {
112 #if HAVE_THREADS && OPENSSL_VERSION_NUMBER < 0x10100000L
113  if (CRYPTO_get_locking_callback() == openssl_lock) {
114  int i;
115  CRYPTO_set_locking_callback(NULL);
116  for (i = 0; i < CRYPTO_num_locks(); i++)
117  pthread_mutex_destroy(&openssl_mutexes[i]);
118  av_free(openssl_mutexes);
119  }
120 #endif
121  }
123 }
124 
125 static int print_tls_error(URLContext *h, int ret)
126 {
127  TLSContext *c = h->priv_data;
128  int printed = 0, e, averr = AVERROR(EIO);
129  if (h->flags & AVIO_FLAG_NONBLOCK) {
130  int err = SSL_get_error(c->ssl, ret);
131  if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
132  return AVERROR(EAGAIN);
133  }
134  while ((e = ERR_get_error()) != 0) {
135  av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(e, NULL));
136  printed = 1;
137  }
138  if (c->io_err) {
139  av_log(h, AV_LOG_ERROR, "IO error: %s\n", av_err2str(c->io_err));
140  printed = 1;
141  averr = c->io_err;
142  c->io_err = 0;
143  }
144  if (!printed)
145  av_log(h, AV_LOG_ERROR, "Unknown error\n");
146  return averr;
147 }
148 
149 static int tls_close(URLContext *h)
150 {
151  TLSContext *c = h->priv_data;
152  if (c->ssl) {
153  SSL_shutdown(c->ssl);
154  SSL_free(c->ssl);
155  }
156  if (c->ctx)
157  SSL_CTX_free(c->ctx);
158  ffurl_closep(&c->tls_shared.tcp);
159 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
160  if (c->url_bio_method)
161  BIO_meth_free(c->url_bio_method);
162 #endif
164  return 0;
165 }
166 
167 static int url_bio_create(BIO *b)
168 {
169 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
170  BIO_set_init(b, 1);
171  BIO_set_data(b, NULL);
172  BIO_set_flags(b, 0);
173 #else
174  b->init = 1;
175  b->ptr = NULL;
176  b->flags = 0;
177 #endif
178  return 1;
179 }
180 
181 static int url_bio_destroy(BIO *b)
182 {
183  return 1;
184 }
185 
186 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
187 #define GET_BIO_DATA(x) BIO_get_data(x)
188 #else
189 #define GET_BIO_DATA(x) (x)->ptr
190 #endif
191 
192 static int url_bio_bread(BIO *b, char *buf, int len)
193 {
195  int ret = ffurl_read(c->tls_shared.tcp, buf, len);
196  if (ret >= 0)
197  return ret;
198  BIO_clear_retry_flags(b);
199  if (ret == AVERROR_EXIT)
200  return 0;
201  if (ret == AVERROR(EAGAIN))
202  BIO_set_retry_read(b);
203  else
204  c->io_err = ret;
205  return -1;
206 }
207 
208 static int url_bio_bwrite(BIO *b, const char *buf, int len)
209 {
211  int ret = ffurl_write(c->tls_shared.tcp, buf, len);
212  if (ret >= 0)
213  return ret;
214  BIO_clear_retry_flags(b);
215  if (ret == AVERROR_EXIT)
216  return 0;
217  if (ret == AVERROR(EAGAIN))
218  BIO_set_retry_write(b);
219  else
220  c->io_err = ret;
221  return -1;
222 }
223 
224 static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
225 {
226  if (cmd == BIO_CTRL_FLUSH) {
227  BIO_clear_retry_flags(b);
228  return 1;
229  }
230  return 0;
231 }
232 
233 static int url_bio_bputs(BIO *b, const char *str)
234 {
235  return url_bio_bwrite(b, str, strlen(str));
236 }
237 
238 #if OPENSSL_VERSION_NUMBER < 0x1010000fL
239 static BIO_METHOD url_bio_method = {
240  .type = BIO_TYPE_SOURCE_SINK,
241  .name = "urlprotocol bio",
242  .bwrite = url_bio_bwrite,
243  .bread = url_bio_bread,
244  .bputs = url_bio_bputs,
245  .bgets = NULL,
246  .ctrl = url_bio_ctrl,
247  .create = url_bio_create,
248  .destroy = url_bio_destroy,
249 };
250 #endif
251 
252 static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
253 {
254  TLSContext *p = h->priv_data;
255  TLSShared *c = &p->tls_shared;
256  BIO *bio;
257  int ret;
258 
259  if ((ret = ff_openssl_init()) < 0)
260  return ret;
261 
262  if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0)
263  goto fail;
264 
265  // We want to support all versions of TLS >= 1.0, but not the deprecated
266  // and insecure SSLv2 and SSLv3. Despite the name, SSLv23_*_method()
267  // enables support for all versions of SSL and TLS, and we then disable
268  // support for the old protocols immediately after creating the context.
269  p->ctx = SSL_CTX_new(c->listen ? SSLv23_server_method() : SSLv23_client_method());
270  if (!p->ctx) {
271  av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
272  ret = AVERROR(EIO);
273  goto fail;
274  }
275  SSL_CTX_set_options(p->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
276  if (c->ca_file) {
277  if (!SSL_CTX_load_verify_locations(p->ctx, c->ca_file, NULL))
278  av_log(h, AV_LOG_ERROR, "SSL_CTX_load_verify_locations %s\n", ERR_error_string(ERR_get_error(), NULL));
279  }
280  if (c->cert_file && !SSL_CTX_use_certificate_chain_file(p->ctx, c->cert_file)) {
281  av_log(h, AV_LOG_ERROR, "Unable to load cert file %s: %s\n",
282  c->cert_file, ERR_error_string(ERR_get_error(), NULL));
283  ret = AVERROR(EIO);
284  goto fail;
285  }
286  if (c->key_file && !SSL_CTX_use_PrivateKey_file(p->ctx, c->key_file, SSL_FILETYPE_PEM)) {
287  av_log(h, AV_LOG_ERROR, "Unable to load key file %s: %s\n",
288  c->key_file, ERR_error_string(ERR_get_error(), NULL));
289  ret = AVERROR(EIO);
290  goto fail;
291  }
292  // Note, this doesn't check that the peer certificate actually matches
293  // the requested hostname.
294  if (c->verify)
295  SSL_CTX_set_verify(p->ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
296  p->ssl = SSL_new(p->ctx);
297  if (!p->ssl) {
298  av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
299  ret = AVERROR(EIO);
300  goto fail;
301  }
302 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
303  p->url_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "urlprotocol bio");
304  BIO_meth_set_write(p->url_bio_method, url_bio_bwrite);
305  BIO_meth_set_read(p->url_bio_method, url_bio_bread);
306  BIO_meth_set_puts(p->url_bio_method, url_bio_bputs);
307  BIO_meth_set_ctrl(p->url_bio_method, url_bio_ctrl);
308  BIO_meth_set_create(p->url_bio_method, url_bio_create);
309  BIO_meth_set_destroy(p->url_bio_method, url_bio_destroy);
310  bio = BIO_new(p->url_bio_method);
311  BIO_set_data(bio, p);
312 #else
313  bio = BIO_new(&url_bio_method);
314  bio->ptr = p;
315 #endif
316  SSL_set_bio(p->ssl, bio, bio);
317  if (!c->listen && !c->numerichost)
318  SSL_set_tlsext_host_name(p->ssl, c->host);
319  ret = c->listen ? SSL_accept(p->ssl) : SSL_connect(p->ssl);
320  if (ret == 0) {
321  av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n");
322  ret = AVERROR(EIO);
323  goto fail;
324  } else if (ret < 0) {
325  ret = print_tls_error(h, ret);
326  goto fail;
327  }
328 
329  return 0;
330 fail:
331  tls_close(h);
332  return ret;
333 }
334 
335 static int tls_read(URLContext *h, uint8_t *buf, int size)
336 {
337  TLSContext *c = h->priv_data;
338  int ret;
339  // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
340  c->tls_shared.tcp->flags &= ~AVIO_FLAG_NONBLOCK;
341  c->tls_shared.tcp->flags |= h->flags & AVIO_FLAG_NONBLOCK;
342  ret = SSL_read(c->ssl, buf, size);
343  if (ret > 0)
344  return ret;
345  if (ret == 0)
346  return AVERROR_EOF;
347  return print_tls_error(h, ret);
348 }
349 
350 static int tls_write(URLContext *h, const uint8_t *buf, int size)
351 {
352  TLSContext *c = h->priv_data;
353  int ret;
354  // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
355  c->tls_shared.tcp->flags &= ~AVIO_FLAG_NONBLOCK;
356  c->tls_shared.tcp->flags |= h->flags & AVIO_FLAG_NONBLOCK;
357  ret = SSL_write(c->ssl, buf, size);
358  if (ret > 0)
359  return ret;
360  if (ret == 0)
361  return AVERROR_EOF;
362  return print_tls_error(h, ret);
363 }
364 
366 {
367  TLSContext *c = h->priv_data;
368  return ffurl_get_file_handle(c->tls_shared.tcp);
369 }
370 
372 {
373  TLSContext *s = h->priv_data;
374  return ffurl_get_short_seek(s->tls_shared.tcp);
375 }
376 
377 static const AVOption options[] = {
378  TLS_COMMON_OPTIONS(TLSContext, tls_shared),
379  { NULL }
380 };
381 
382 static const AVClass tls_class = {
383  .class_name = "tls",
384  .item_name = av_default_item_name,
385  .option = options,
386  .version = LIBAVUTIL_VERSION_INT,
387 };
388 
390  .name = "tls",
391  .url_open2 = tls_open,
392  .url_read = tls_read,
393  .url_write = tls_write,
394  .url_close = tls_close,
395  .url_get_file_handle = tls_get_file_handle,
396  .url_get_short_seek = tls_get_short_seek,
397  .priv_data_size = sizeof(TLSContext),
399  .priv_data_class = &tls_class,
400 };
pthread_mutex_t
_fmutex pthread_mutex_t
Definition: os2threads.h:53
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:33
thread.h
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
pthread_mutex_init
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:104
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
AVOption
AVOption.
Definition: opt.h:346
b
#define b
Definition: input.c:41
AVDictionary
Definition: dict.c:34
URLProtocol
Definition: url.h:51
os_support.h
ff_openssl_deinit
void ff_openssl_deinit(void)
Definition: tls_openssl.c:107
ff_unlock_avformat
int ff_unlock_avformat(void)
Definition: utils.c:55
TLS_COMMON_OPTIONS
#define TLS_COMMON_OPTIONS(pstruct, options_field)
Definition: tls.h:46
tls_class
static const AVClass tls_class
Definition: tls_openssl.c:382
fail
#define fail()
Definition: checkasm.h:179
ffurl_get_short_seek
int ffurl_get_short_seek(void *urlcontext)
Return the current short seek threshold value for this URL.
Definition: avio.c:838
url_bio_create
static int url_bio_create(BIO *b)
Definition: tls_openssl.c:167
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:189
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:180
s
#define s(width, name)
Definition: cbs_vp9.c:198
tls_write
static int tls_write(URLContext *h, const uint8_t *buf, int size)
Definition: tls_openssl.c:350
ff_tls_protocol
const URLProtocol ff_tls_protocol
Definition: tls_openssl.c:389
internal.h
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
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:237
parseutils.h
url_bio_ctrl
static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
Definition: tls_openssl.c:224
ff_openssl_init
int ff_openssl_init(void)
Definition: tls_openssl.c:70
url_bio_destroy
static int url_bio_destroy(BIO *b)
Definition: tls_openssl.c:181
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:208
tls_open
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
Definition: tls_openssl.c:252
pthread_mutex_unlock
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:82
url_bio_bread
static int url_bio_bread(BIO *b, char *buf, int len)
Definition: tls_openssl.c:192
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:121
TLSContext::ctx
SSL_CTX * ctx
Definition: tls_openssl.c:44
size
int size
Definition: twinvq_data.h:10344
TLSContext::tls_shared
TLSShared tls_shared
Definition: tls_gnutls.c:50
URLProtocol::name
const char * name
Definition: url.h:52
ff_lock_avformat
int ff_lock_avformat(void)
Definition: utils.c:50
options
static const AVOption options[]
Definition: tls_openssl.c:377
TLSContext::io_err
int io_err
Definition: tls_gnutls.c:54
line
Definition: graph2dot.c:48
tls_get_file_handle
static int tls_get_file_handle(URLContext *h)
Definition: tls_openssl.c:365
pthread_mutex_destroy
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:112
TLSContext::ssl
SSL * ssl
Definition: tls_openssl.c:45
URLContext
Definition: url.h:35
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
url.h
print_tls_error
static int print_tls_error(URLContext *h, int ret)
Definition: tls_openssl.c:125
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:588
ff_tls_open_underlying
int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AVDictionary **options)
Definition: tls.c:67
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:71
averr
int averr
Definition: nvenc.c:113
avformat.h
network.h
tls.h
tls_get_short_seek
static int tls_get_short_seek(URLContext *h)
Definition: tls_openssl.c:371
mode
mode
Definition: ebur128.h:83
tls_read
static int tls_read(URLContext *h, uint8_t *buf, int size)
Definition: tls_openssl.c:335
avutil.h
mem.h
url_bio_method
static BIO_METHOD url_bio_method
Definition: tls_openssl.c:239
TLSShared
Definition: tls.h:29
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVIO_FLAG_NONBLOCK
#define AVIO_FLAG_NONBLOCK
Use non-blocking mode.
Definition: avio.h:636
TLSContext::ctx
struct tls * ctx
Definition: tls_libtls.c:37
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
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:58
avstring.h
tls_close
static int tls_close(URLContext *h)
Definition: tls_openssl.c:149
ffurl_get_file_handle
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
Definition: avio.c:814
url_bio_bputs
static int url_bio_bputs(BIO *b, const char *str)
Definition: tls_openssl.c:233
pthread_mutex_lock
#define pthread_mutex_lock(a)
Definition: ffprobe.c:78
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