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 && 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  if (h->flags & AVIO_FLAG_NONBLOCK) {
128  int err = SSL_get_error(c->ssl, ret);
129  if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
130  return AVERROR(EAGAIN);
131  }
132  av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
133  return AVERROR(EIO);
134 }
135 
136 static int tls_close(URLContext *h)
137 {
138  TLSContext *c = h->priv_data;
139  if (c->ssl) {
140  SSL_shutdown(c->ssl);
141  SSL_free(c->ssl);
142  }
143  if (c->ctx)
144  SSL_CTX_free(c->ctx);
145  ffurl_closep(&c->tls_shared.tcp);
146 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
147  if (c->url_bio_method)
148  BIO_meth_free(c->url_bio_method);
149 #endif
151  return 0;
152 }
153 
154 static int url_bio_create(BIO *b)
155 {
156 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
157  BIO_set_init(b, 1);
158  BIO_set_data(b, NULL);
159  BIO_set_flags(b, 0);
160 #else
161  b->init = 1;
162  b->ptr = NULL;
163  b->flags = 0;
164 #endif
165  return 1;
166 }
167 
168 static int url_bio_destroy(BIO *b)
169 {
170  return 1;
171 }
172 
173 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
174 #define GET_BIO_DATA(x) BIO_get_data(x)
175 #else
176 #define GET_BIO_DATA(x) (x)->ptr
177 #endif
178 
179 static int url_bio_bread(BIO *b, char *buf, int len)
180 {
182  int ret = ffurl_read(h, buf, len);
183  if (ret >= 0)
184  return ret;
185  BIO_clear_retry_flags(b);
186  if (ret == AVERROR(EAGAIN))
187  BIO_set_retry_read(b);
188  if (ret == AVERROR_EXIT)
189  return 0;
190  return -1;
191 }
192 
193 static int url_bio_bwrite(BIO *b, const char *buf, int len)
194 {
196  int ret = ffurl_write(h, buf, len);
197  if (ret >= 0)
198  return ret;
199  BIO_clear_retry_flags(b);
200  if (ret == AVERROR(EAGAIN))
201  BIO_set_retry_write(b);
202  if (ret == AVERROR_EXIT)
203  return 0;
204  return -1;
205 }
206 
207 static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
208 {
209  if (cmd == BIO_CTRL_FLUSH) {
210  BIO_clear_retry_flags(b);
211  return 1;
212  }
213  return 0;
214 }
215 
216 static int url_bio_bputs(BIO *b, const char *str)
217 {
218  return url_bio_bwrite(b, str, strlen(str));
219 }
220 
221 #if OPENSSL_VERSION_NUMBER < 0x1010000fL
222 static BIO_METHOD url_bio_method = {
223  .type = BIO_TYPE_SOURCE_SINK,
224  .name = "urlprotocol bio",
225  .bwrite = url_bio_bwrite,
226  .bread = url_bio_bread,
227  .bputs = url_bio_bputs,
228  .bgets = NULL,
229  .ctrl = url_bio_ctrl,
230  .create = url_bio_create,
231  .destroy = url_bio_destroy,
232 };
233 #endif
234 
235 static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
236 {
237  TLSContext *p = h->priv_data;
238  TLSShared *c = &p->tls_shared;
239  BIO *bio;
240  int ret;
241 
242  if ((ret = ff_openssl_init()) < 0)
243  return ret;
244 
245  if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0)
246  goto fail;
247 
248  // We want to support all versions of TLS >= 1.0, but not the deprecated
249  // and insecure SSLv2 and SSLv3. Despite the name, SSLv23_*_method()
250  // enables support for all versions of SSL and TLS, and we then disable
251  // support for the old protocols immediately after creating the context.
252  p->ctx = SSL_CTX_new(c->listen ? SSLv23_server_method() : SSLv23_client_method());
253  if (!p->ctx) {
254  av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
255  ret = AVERROR(EIO);
256  goto fail;
257  }
258  SSL_CTX_set_options(p->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
259  if (c->ca_file) {
260  if (!SSL_CTX_load_verify_locations(p->ctx, c->ca_file, NULL))
261  av_log(h, AV_LOG_ERROR, "SSL_CTX_load_verify_locations %s\n", ERR_error_string(ERR_get_error(), NULL));
262  }
263  if (c->cert_file && !SSL_CTX_use_certificate_chain_file(p->ctx, c->cert_file)) {
264  av_log(h, AV_LOG_ERROR, "Unable to load cert file %s: %s\n",
265  c->cert_file, ERR_error_string(ERR_get_error(), NULL));
266  ret = AVERROR(EIO);
267  goto fail;
268  }
269  if (c->key_file && !SSL_CTX_use_PrivateKey_file(p->ctx, c->key_file, SSL_FILETYPE_PEM)) {
270  av_log(h, AV_LOG_ERROR, "Unable to load key file %s: %s\n",
271  c->key_file, ERR_error_string(ERR_get_error(), NULL));
272  ret = AVERROR(EIO);
273  goto fail;
274  }
275  // Note, this doesn't check that the peer certificate actually matches
276  // the requested hostname.
277  if (c->verify)
278  SSL_CTX_set_verify(p->ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
279  p->ssl = SSL_new(p->ctx);
280  if (!p->ssl) {
281  av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
282  ret = AVERROR(EIO);
283  goto fail;
284  }
285 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
286  p->url_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "urlprotocol bio");
287  BIO_meth_set_write(p->url_bio_method, url_bio_bwrite);
288  BIO_meth_set_read(p->url_bio_method, url_bio_bread);
289  BIO_meth_set_puts(p->url_bio_method, url_bio_bputs);
290  BIO_meth_set_ctrl(p->url_bio_method, url_bio_ctrl);
291  BIO_meth_set_create(p->url_bio_method, url_bio_create);
292  BIO_meth_set_destroy(p->url_bio_method, url_bio_destroy);
293  bio = BIO_new(p->url_bio_method);
294  BIO_set_data(bio, c->tcp);
295 #else
296  bio = BIO_new(&url_bio_method);
297  bio->ptr = c->tcp;
298 #endif
299  SSL_set_bio(p->ssl, bio, bio);
300  if (!c->listen && !c->numerichost)
301  SSL_set_tlsext_host_name(p->ssl, c->host);
302  ret = c->listen ? SSL_accept(p->ssl) : SSL_connect(p->ssl);
303  if (ret == 0) {
304  av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n");
305  ret = AVERROR(EIO);
306  goto fail;
307  } else if (ret < 0) {
308  ret = print_tls_error(h, ret);
309  goto fail;
310  }
311 
312  return 0;
313 fail:
314  tls_close(h);
315  return ret;
316 }
317 
318 static int tls_read(URLContext *h, uint8_t *buf, int size)
319 {
320  TLSContext *c = h->priv_data;
321  int ret;
322  // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
323  c->tls_shared.tcp->flags &= ~AVIO_FLAG_NONBLOCK;
324  c->tls_shared.tcp->flags |= h->flags & AVIO_FLAG_NONBLOCK;
325  ret = SSL_read(c->ssl, buf, size);
326  if (ret > 0)
327  return ret;
328  if (ret == 0)
329  return AVERROR_EOF;
330  return print_tls_error(h, ret);
331 }
332 
333 static int tls_write(URLContext *h, const uint8_t *buf, int size)
334 {
335  TLSContext *c = h->priv_data;
336  int ret;
337  // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
338  c->tls_shared.tcp->flags &= ~AVIO_FLAG_NONBLOCK;
339  c->tls_shared.tcp->flags |= h->flags & AVIO_FLAG_NONBLOCK;
340  ret = SSL_write(c->ssl, buf, size);
341  if (ret > 0)
342  return ret;
343  if (ret == 0)
344  return AVERROR_EOF;
345  return print_tls_error(h, ret);
346 }
347 
349 {
350  TLSContext *c = h->priv_data;
351  return ffurl_get_file_handle(c->tls_shared.tcp);
352 }
353 
355 {
356  TLSContext *s = h->priv_data;
357  return ffurl_get_short_seek(s->tls_shared.tcp);
358 }
359 
360 static const AVOption options[] = {
361  TLS_COMMON_OPTIONS(TLSContext, tls_shared),
362  { NULL }
363 };
364 
365 static const AVClass tls_class = {
366  .class_name = "tls",
367  .item_name = av_default_item_name,
368  .option = options,
369  .version = LIBAVUTIL_VERSION_INT,
370 };
371 
373  .name = "tls",
374  .url_open2 = tls_open,
375  .url_read = tls_read,
376  .url_write = tls_write,
377  .url_close = tls_close,
378  .url_get_file_handle = tls_get_file_handle,
379  .url_get_short_seek = tls_get_short_seek,
380  .priv_data_size = sizeof(TLSContext),
382  .priv_data_class = &tls_class,
383 };
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: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:104
internal.h
AVOption
AVOption.
Definition: opt.h:248
b
#define b
Definition: input.c:41
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:106
ff_unlock_avformat
int ff_unlock_avformat(void)
Definition: utils.c:84
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:365
fail
#define fail()
Definition: checkasm.h:133
url_bio_create
static int url_bio_create(BIO *b)
Definition: tls_openssl.c:154
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:176
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:194
s
#define s(width, name)
Definition: cbs_vp9.c:257
tls_write
static int tls_write(URLContext *h, const uint8_t *buf, int size)
Definition: tls_openssl.c:333
ff_tls_protocol
const URLProtocol ff_tls_protocol
Definition: tls_openssl.c:372
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:235
parseutils.h
url_bio_ctrl
static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
Definition: tls_openssl.c:207
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:168
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:193
tls_open
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
Definition: tls_openssl.c:235
pthread_mutex_unlock
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:67
url_bio_bread
static int url_bio_bread(BIO *b, char *buf, int len)
Definition: tls_openssl.c:179
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:55
ff_lock_avformat
int ff_lock_avformat(void)
Definition: utils.c:79
options
static const AVOption options[]
Definition: tls_openssl.c:360
line
Definition: graph2dot.c:48
tls_get_file_handle
static int tls_get_file_handle(URLContext *h)
Definition: tls_openssl.c:348
ffurl_get_short_seek
int ffurl_get_short_seek(URLContext *h)
Return the current short seek threshold value for this URL.
Definition: avio.c:647
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
i
int i
Definition: input.c:407
URLContext
Definition: url.h:38
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:124
len
int len
Definition: vorbis_enc_data.h:452
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:441
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:404
tls_get_short_seek
static int tls_get_short_seek(URLContext *h)
Definition: tls_openssl.c:354
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:418
tls_read
static int tls_read(URLContext *h, uint8_t *buf, int size)
Definition: tls_openssl.c:318
avutil.h
url_bio_method
static BIO_METHOD url_bio_method
Definition: tls_openssl.c:222
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:693
TLSContext::ctx
struct tls * ctx
Definition: tls_libtls.c:37
convert_header.str
string str
Definition: convert_header.py:20
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
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:136
ffurl_get_file_handle
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
Definition: avio.c:623
url_bio_bputs
static int url_bio_bputs(BIO *b, const char *str)
Definition: tls_openssl.c:216
pthread_mutex_lock
#define pthread_mutex_lock(a)
Definition: ffprobe.c:63