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