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);
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 {
181  URLContext *h = GET_BIO_DATA(b);
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 {
195  URLContext *h = GET_BIO_DATA(b);
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
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
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;
352 }
353 
354 static const AVOption options[] = {
356  { NULL }
357 };
358 
359 static const AVClass tls_class = {
360  .class_name = "tls",
361  .item_name = av_default_item_name,
362  .option = options,
363  .version = LIBAVUTIL_VERSION_INT,
364 };
365 
367  .name = "tls",
368  .url_open2 = tls_open,
369  .url_read = tls_read,
370  .url_write = tls_write,
371  .url_close = tls_close,
372  .url_get_file_handle = tls_get_file_handle,
373  .priv_data_size = sizeof(TLSContext),
375  .priv_data_class = &tls_class,
376 };
#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:62
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:423
static int url_bio_bwrite(BIO *b, const char *buf, int len)
Definition: tls_openssl.c:193
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:179
uint8_t
AVOptions.
miscellaneous OS support macros and functions.
static int url_bio_bputs(BIO *b, const char *str)
Definition: tls_openssl.c:216
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:176
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:348
#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
Definition: graph2dot.c:48
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
Definition: tls_openssl.c:235
#define fail()
Definition: checkasm.h:123
char * host
Definition: tls.h:36
static const AVOption options[]
Definition: tls_openssl.c:354
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:359
int ff_unlock_avformat(void)
Definition: utils.c:84
#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:104
char * cert_file
Definition: tls.h:32
static int tls_write(URLContext *h, const uint8_t *buf, int size)
Definition: tls_openssl.c:333
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:66
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
Definition: avio.c:628
#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:446
static int url_bio_destroy(BIO *b)
Definition: tls_openssl.c:168
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
Definition: url.h:38
static int tls_read(URLContext *h, uint8_t *buf, int size)
Definition: tls_openssl.c:318
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:366
misc parsing utilities
const char * name
Definition: url.h:55
#define flags(name, subs,...)
Definition: cbs_av1.c:560
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:41
static BIO_METHOD url_bio_method
Definition: tls_openssl.c:222
int numerichost
Definition: tls.h:39
static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
Definition: tls_openssl.c:207
#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:409
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:154
int i
Definition: input.c:407