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  if (c->tls_shared.tcp)
147 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
148  if (c->url_bio_method)
149  BIO_meth_free(c->url_bio_method);
150 #endif
152  return 0;
153 }
154 
155 static int url_bio_create(BIO *b)
156 {
157 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
158  BIO_set_init(b, 1);
159  BIO_set_data(b, NULL);
160  BIO_set_flags(b, 0);
161 #else
162  b->init = 1;
163  b->ptr = NULL;
164  b->flags = 0;
165 #endif
166  return 1;
167 }
168 
169 static int url_bio_destroy(BIO *b)
170 {
171  return 1;
172 }
173 
174 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
175 #define GET_BIO_DATA(x) BIO_get_data(x)
176 #else
177 #define GET_BIO_DATA(x) (x)->ptr
178 #endif
179 
180 static int url_bio_bread(BIO *b, char *buf, int len)
181 {
182  URLContext *h = GET_BIO_DATA(b);
183  int ret = ffurl_read(h, buf, len);
184  if (ret >= 0)
185  return ret;
186  BIO_clear_retry_flags(b);
187  if (ret == AVERROR(EAGAIN))
188  BIO_set_retry_read(b);
189  if (ret == AVERROR_EXIT)
190  return 0;
191  return -1;
192 }
193 
194 static int url_bio_bwrite(BIO *b, const char *buf, int len)
195 {
196  URLContext *h = GET_BIO_DATA(b);
197  int ret = ffurl_write(h, buf, len);
198  if (ret >= 0)
199  return ret;
200  BIO_clear_retry_flags(b);
201  if (ret == AVERROR(EAGAIN))
202  BIO_set_retry_write(b);
203  if (ret == AVERROR_EXIT)
204  return 0;
205  return -1;
206 }
207 
208 static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
209 {
210  if (cmd == BIO_CTRL_FLUSH) {
211  BIO_clear_retry_flags(b);
212  return 1;
213  }
214  return 0;
215 }
216 
217 static int url_bio_bputs(BIO *b, const char *str)
218 {
219  return url_bio_bwrite(b, str, strlen(str));
220 }
221 
222 #if OPENSSL_VERSION_NUMBER < 0x1010000fL
223 static BIO_METHOD url_bio_method = {
224  .type = BIO_TYPE_SOURCE_SINK,
225  .name = "urlprotocol bio",
226  .bwrite = url_bio_bwrite,
227  .bread = url_bio_bread,
228  .bputs = url_bio_bputs,
229  .bgets = NULL,
230  .ctrl = url_bio_ctrl,
231  .create = url_bio_create,
232  .destroy = url_bio_destroy,
233 };
234 #endif
235 
236 static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
237 {
238  TLSContext *p = h->priv_data;
239  TLSShared *c = &p->tls_shared;
240  BIO *bio;
241  int ret;
242 
243  if ((ret = ff_openssl_init()) < 0)
244  return ret;
245 
246  if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0)
247  goto fail;
248 
249  // We want to support all versions of TLS >= 1.0, but not the deprecated
250  // and insecure SSLv2 and SSLv3. Despite the name, SSLv23_*_method()
251  // enables support for all versions of SSL and TLS, and we then disable
252  // support for the old protocols immediately after creating the context.
253  p->ctx = SSL_CTX_new(c->listen ? SSLv23_server_method() : SSLv23_client_method());
254  if (!p->ctx) {
255  av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
256  ret = AVERROR(EIO);
257  goto fail;
258  }
259  SSL_CTX_set_options(p->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
260  if (c->ca_file) {
261  if (!SSL_CTX_load_verify_locations(p->ctx, c->ca_file, NULL))
262  av_log(h, AV_LOG_ERROR, "SSL_CTX_load_verify_locations %s\n", ERR_error_string(ERR_get_error(), NULL));
263  }
264  if (c->cert_file && !SSL_CTX_use_certificate_chain_file(p->ctx, c->cert_file)) {
265  av_log(h, AV_LOG_ERROR, "Unable to load cert file %s: %s\n",
266  c->cert_file, ERR_error_string(ERR_get_error(), NULL));
267  ret = AVERROR(EIO);
268  goto fail;
269  }
270  if (c->key_file && !SSL_CTX_use_PrivateKey_file(p->ctx, c->key_file, SSL_FILETYPE_PEM)) {
271  av_log(h, AV_LOG_ERROR, "Unable to load key file %s: %s\n",
272  c->key_file, ERR_error_string(ERR_get_error(), NULL));
273  ret = AVERROR(EIO);
274  goto fail;
275  }
276  // Note, this doesn't check that the peer certificate actually matches
277  // the requested hostname.
278  if (c->verify)
279  SSL_CTX_set_verify(p->ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
280  p->ssl = SSL_new(p->ctx);
281  if (!p->ssl) {
282  av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
283  ret = AVERROR(EIO);
284  goto fail;
285  }
286 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
287  p->url_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "urlprotocol bio");
288  BIO_meth_set_write(p->url_bio_method, url_bio_bwrite);
289  BIO_meth_set_read(p->url_bio_method, url_bio_bread);
290  BIO_meth_set_puts(p->url_bio_method, url_bio_bputs);
291  BIO_meth_set_ctrl(p->url_bio_method, url_bio_ctrl);
292  BIO_meth_set_create(p->url_bio_method, url_bio_create);
293  BIO_meth_set_destroy(p->url_bio_method, url_bio_destroy);
294  bio = BIO_new(p->url_bio_method);
295  BIO_set_data(bio, c->tcp);
296 #else
297  bio = BIO_new(&url_bio_method);
298  bio->ptr = c->tcp;
299 #endif
300  SSL_set_bio(p->ssl, bio, bio);
301  if (!c->listen && !c->numerichost)
302  SSL_set_tlsext_host_name(p->ssl, c->host);
303  ret = c->listen ? SSL_accept(p->ssl) : SSL_connect(p->ssl);
304  if (ret == 0) {
305  av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n");
306  ret = AVERROR(EIO);
307  goto fail;
308  } else if (ret < 0) {
309  ret = print_tls_error(h, ret);
310  goto fail;
311  }
312 
313  return 0;
314 fail:
315  tls_close(h);
316  return ret;
317 }
318 
319 static int tls_read(URLContext *h, uint8_t *buf, int size)
320 {
321  TLSContext *c = h->priv_data;
322  int ret;
323  // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
326  ret = SSL_read(c->ssl, buf, size);
327  if (ret > 0)
328  return ret;
329  if (ret == 0)
330  return AVERROR_EOF;
331  return print_tls_error(h, ret);
332 }
333 
334 static int tls_write(URLContext *h, const 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
341  ret = SSL_write(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 
350 {
351  TLSContext *c = h->priv_data;
353 }
354 
355 static const AVOption options[] = {
357  { NULL }
358 };
359 
360 static const AVClass tls_class = {
361  .class_name = "tls",
362  .item_name = av_default_item_name,
363  .option = options,
364  .version = LIBAVUTIL_VERSION_INT,
365 };
366 
368  .name = "tls",
369  .url_open2 = tls_open,
370  .url_read = tls_read,
371  .url_write = tls_write,
372  .url_close = tls_close,
373  .url_get_file_handle = tls_get_file_handle,
374  .priv_data_size = sizeof(TLSContext),
376  .priv_data_class = &tls_class,
377 };
#define NULL
Definition: coverity.c:32
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:111
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:61
AVOption.
Definition: opt.h:246
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:420
static int url_bio_bwrite(BIO *b, const char *buf, int len)
Definition: tls_openssl.c:194
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
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:180
uint8_t
AVOptions.
miscellaneous OS support macros and functions.
static int url_bio_bputs(BIO *b, const char *str)
Definition: tls_openssl.c:217
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:177
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:349
#define av_log(a,...)
SSL * ssl
Definition: tls_openssl.c:45
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
Definition: graph2dot.c:48
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
Definition: tls_openssl.c:236
#define fail()
Definition: checkasm.h:122
char * host
Definition: tls.h:36
static const AVOption options[]
Definition: tls_openssl.c:355
void ff_openssl_deinit(void)
Definition: tls_openssl.c:106
#define b
Definition: input.c:41
static const AVClass tls_class
Definition: tls_openssl.c:360
int ff_unlock_avformat(void)
Definition: utils.c:88
#define TLS_COMMON_OPTIONS(pstruct, options_field)
Definition: tls.h:45
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:103
char * cert_file
Definition: tls.h:32
static int tls_write(URLContext *h, const uint8_t *buf, int size)
Definition: tls_openssl.c:334
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:65
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
Definition: avio.c:625
#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
static int url_bio_destroy(BIO *b)
Definition: tls_openssl.c:169
static int print_tls_error(URLContext *h, int ret)
Definition: tls_openssl.c:124
SSL_CTX * ctx
Definition: tls_openssl.c:44
#define AVIO_FLAG_NONBLOCK
Use non-blocking mode.
Definition: avio.h:693
int ff_openssl_init(void)
Definition: tls_openssl.c:69
TLSShared tls_shared
Definition: tls_gnutls.c:50
void * buf
Definition: avisynth_c.h:766
Definition: url.h:38
static int tls_read(URLContext *h, uint8_t *buf, int size)
Definition: tls_openssl.c:319
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:136
const URLProtocol ff_tls_protocol
Definition: tls_openssl.c:367
misc parsing utilities
const char * name
Definition: url.h:55
#define flags(name, subs,...)
Definition: cbs_av1.c:564
int ffurl_close(URLContext *h)
Definition: avio.c:466
Main libavformat public API header.
common internal api header.
_fmutex pthread_mutex_t
Definition: os2threads.h:52
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:41
static BIO_METHOD url_bio_method
Definition: tls_openssl.c:223
int numerichost
Definition: tls.h:39
static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
Definition: tls_openssl.c:208
#define av_free(p)
int len
int ff_lock_avformat(void)
Definition: utils.c:83
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:406
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:155