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