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  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);
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 {
194  TLSContext *c = GET_BIO_DATA(b);
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 {
210  TLSContext *c = GET_BIO_DATA(b);
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
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
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;
369 }
370 
372 {
373  TLSContext *s = h->priv_data;
375 }
376 
377 static const AVOption options[] = {
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 };
#define NULL
Definition: coverity.c:32
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:112
static int openssl_init
Definition: tls_openssl.c:39
#define URL_PROTOCOL_FLAG_NETWORK
Definition: url.h:34
#define pthread_mutex_lock(a)
Definition: ffprobe.c:63
AVOption.
Definition: opt.h:248
int verify
Definition: tls.h:31
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
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:415
static int url_bio_bwrite(BIO *b, const char *buf, int len)
Definition: tls_openssl.c:208
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
Convenience header that includes libavutil&#39;s core.
GLint GLenum type
Definition: opengl_enc.c:104
int flags
Definition: url.h:43
int listen
Definition: tls.h:34
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
static int url_bio_bread(BIO *b, char *buf, int len)
Definition: tls_openssl.c:192
uint8_t
AVOptions.
miscellaneous OS support macros and functions.
static int url_bio_bputs(BIO *b, const char *str)
Definition: tls_openssl.c:233
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
#define GET_BIO_DATA(x)
Definition: tls_openssl.c:189
Definition: tls.h:29
#define AVERROR_EOF
End of file.
Definition: error.h:55
ptrdiff_t size
Definition: opengl_enc.c:100
static int tls_get_file_handle(URLContext *h)
Definition: tls_openssl.c:365
#define av_log(a,...)
SSL * ssl
Definition: tls_openssl.c:45
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
int io_err
Definition: tls_gnutls.c:54
Definition: graph2dot.c:48
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
Definition: tls_openssl.c:252
#define fail()
Definition: checkasm.h:133
char * host
Definition: tls.h:36
static const AVOption options[]
Definition: tls_openssl.c:377
void ff_openssl_deinit(void)
Definition: tls_openssl.c:107
#define b
Definition: input.c:41
int ffurl_get_short_seek(URLContext *h)
Return the current short seek threshold value for this URL.
Definition: avio.c:644
static const AVClass tls_class
Definition: tls_openssl.c:382
int ff_unlock_avformat(void)
Definition: utils.c:84
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:119
#define TLS_COMMON_OPTIONS(pstruct, options_field)
Definition: tls.h:46
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:104
#define s(width, name)
Definition: cbs_vp9.c:257
char * cert_file
Definition: tls.h:32
static int tls_write(URLContext *h, const uint8_t *buf, int size)
Definition: tls_openssl.c:350
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:67
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
Definition: avio.c:620
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:56
char * ca_file
Definition: tls.h:30
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
Definition: avio.c:438
static int url_bio_destroy(BIO *b)
Definition: tls_openssl.c:181
static int print_tls_error(URLContext *h, int ret)
Definition: tls_openssl.c:125
SSL_CTX * ctx
Definition: tls_openssl.c:44
#define AVIO_FLAG_NONBLOCK
Use non-blocking mode.
Definition: avio.h:693
static int tls_get_short_seek(URLContext *h)
Definition: tls_openssl.c:371
int ff_openssl_init(void)
Definition: tls_openssl.c:70
TLSShared tls_shared
Definition: tls_gnutls.c:50
Definition: url.h:38
static int tls_read(URLContext *h, uint8_t *buf, int size)
Definition: tls_openssl.c:335
Describe the class of an AVClass context structure.
Definition: log.h:67
void * priv_data
Definition: url.h:41
static int tls_close(URLContext *h)
Definition: tls_openssl.c:149
const URLProtocol ff_tls_protocol
Definition: tls_openssl.c:389
misc parsing utilities
int averr
Definition: nvenc.c:89
const char * name
Definition: url.h:55
#define flags(name, subs,...)
Definition: cbs_av1.c:561
Main libavformat public API header.
common internal api header.
_fmutex pthread_mutex_t
Definition: os2threads.h:53
int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AVDictionary **options)
Definition: tls.c:56
struct tls * ctx
Definition: tls_libtls.c:37
URLContext * tcp
Definition: tls.h:42
static BIO_METHOD url_bio_method
Definition: tls_openssl.c:239
int numerichost
Definition: tls.h:40
static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
Definition: tls_openssl.c:224
#define av_free(p)
int len
int ff_lock_avformat(void)
Definition: utils.c:79
unbuffered private I/O API
#define av_malloc_array(a, b)
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
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:401
mode
Use these values in ebur128_init (or&#39;ed).
Definition: ebur128.h:83
char * key_file
Definition: tls.h:33
static int url_bio_create(BIO *b)
Definition: tls_openssl.c:167
int i
Definition: input.c:407