FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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
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  SSL_library_init();
74  SSL_load_error_strings();
75 #if HAVE_THREADS
76  if (!CRYPTO_get_locking_callback()) {
77  int i;
78  openssl_mutexes = av_malloc_array(sizeof(pthread_mutex_t), CRYPTO_num_locks());
79  if (!openssl_mutexes) {
81  return AVERROR(ENOMEM);
82  }
83 
84  for (i = 0; i < CRYPTO_num_locks(); i++)
85  pthread_mutex_init(&openssl_mutexes[i], NULL);
86  CRYPTO_set_locking_callback(openssl_lock);
87 #if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000
88  CRYPTO_set_id_callback(openssl_thread_id);
89 #endif
90  }
91 #endif
92  }
93  openssl_init++;
95 
96  return 0;
97 }
98 
100 {
102  openssl_init--;
103  if (!openssl_init) {
104 #if HAVE_THREADS
105  if (CRYPTO_get_locking_callback() == openssl_lock) {
106  int i;
107  CRYPTO_set_locking_callback(NULL);
108  for (i = 0; i < CRYPTO_num_locks(); i++)
109  pthread_mutex_destroy(&openssl_mutexes[i]);
110  av_free(openssl_mutexes);
111  }
112 #endif
113  }
115 }
116 
117 static int print_tls_error(URLContext *h, int ret)
118 {
119  TLSContext *c = h->priv_data;
120  if (h->flags & AVIO_FLAG_NONBLOCK) {
121  int err = SSL_get_error(c->ssl, ret);
122  if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
123  return AVERROR(EAGAIN);
124  }
125  av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
126  return AVERROR(EIO);
127 }
128 
129 static int tls_close(URLContext *h)
130 {
131  TLSContext *c = h->priv_data;
132  if (c->ssl) {
133  SSL_shutdown(c->ssl);
134  SSL_free(c->ssl);
135  }
136  if (c->ctx)
137  SSL_CTX_free(c->ctx);
138  if (c->tls_shared.tcp)
140 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
141  if (c->url_bio_method)
142  BIO_meth_free(c->url_bio_method);
143 #endif
145  return 0;
146 }
147 
148 static int url_bio_create(BIO *b)
149 {
150 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
151  BIO_set_init(b, 1);
152  BIO_set_data(b, NULL);
153  BIO_set_flags(b, 0);
154 #else
155  b->init = 1;
156  b->ptr = NULL;
157  b->flags = 0;
158 #endif
159  return 1;
160 }
161 
162 static int url_bio_destroy(BIO *b)
163 {
164  return 1;
165 }
166 
167 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
168 #define GET_BIO_DATA(x) BIO_get_data(x)
169 #else
170 #define GET_BIO_DATA(x) (x)->ptr
171 #endif
172 
173 static int url_bio_bread(BIO *b, char *buf, int len)
174 {
175  URLContext *h = GET_BIO_DATA(b);
176  int ret = ffurl_read(h, buf, len);
177  if (ret >= 0)
178  return ret;
179  BIO_clear_retry_flags(b);
180  if (ret == AVERROR(EAGAIN))
181  BIO_set_retry_read(b);
182  if (ret == AVERROR_EXIT)
183  return 0;
184  return -1;
185 }
186 
187 static int url_bio_bwrite(BIO *b, const char *buf, int len)
188 {
189  URLContext *h = GET_BIO_DATA(b);
190  int ret = ffurl_write(h, buf, len);
191  if (ret >= 0)
192  return ret;
193  BIO_clear_retry_flags(b);
194  if (ret == AVERROR(EAGAIN))
195  BIO_set_retry_write(b);
196  if (ret == AVERROR_EXIT)
197  return 0;
198  return -1;
199 }
200 
201 static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
202 {
203  if (cmd == BIO_CTRL_FLUSH) {
204  BIO_clear_retry_flags(b);
205  return 1;
206  }
207  return 0;
208 }
209 
210 static int url_bio_bputs(BIO *b, const char *str)
211 {
212  return url_bio_bwrite(b, str, strlen(str));
213 }
214 
215 #if OPENSSL_VERSION_NUMBER < 0x1010000fL
216 static BIO_METHOD url_bio_method = {
217  .type = BIO_TYPE_SOURCE_SINK,
218  .name = "urlprotocol bio",
219  .bwrite = url_bio_bwrite,
220  .bread = url_bio_bread,
221  .bputs = url_bio_bputs,
222  .bgets = NULL,
223  .ctrl = url_bio_ctrl,
224  .create = url_bio_create,
225  .destroy = url_bio_destroy,
226 };
227 #endif
228 
229 static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
230 {
231  TLSContext *p = h->priv_data;
232  TLSShared *c = &p->tls_shared;
233  BIO *bio;
234  int ret;
235 
236  if ((ret = ff_openssl_init()) < 0)
237  return ret;
238 
239  if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0)
240  goto fail;
241 
242  // We want to support all versions of TLS >= 1.0, but not the deprecated
243  // and insecure SSLv2 and SSLv3. Despite the name, SSLv23_*_method()
244  // enables support for all versions of SSL and TLS, and we then disable
245  // support for the old protocols immediately after creating the context.
246  p->ctx = SSL_CTX_new(c->listen ? SSLv23_server_method() : SSLv23_client_method());
247  if (!p->ctx) {
248  av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
249  ret = AVERROR(EIO);
250  goto fail;
251  }
252  SSL_CTX_set_options(p->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
253  if (c->ca_file) {
254  if (!SSL_CTX_load_verify_locations(p->ctx, c->ca_file, NULL))
255  av_log(h, AV_LOG_ERROR, "SSL_CTX_load_verify_locations %s\n", ERR_error_string(ERR_get_error(), NULL));
256  }
257  if (c->cert_file && !SSL_CTX_use_certificate_chain_file(p->ctx, c->cert_file)) {
258  av_log(h, AV_LOG_ERROR, "Unable to load cert file %s: %s\n",
259  c->cert_file, ERR_error_string(ERR_get_error(), NULL));
260  ret = AVERROR(EIO);
261  goto fail;
262  }
263  if (c->key_file && !SSL_CTX_use_PrivateKey_file(p->ctx, c->key_file, SSL_FILETYPE_PEM)) {
264  av_log(h, AV_LOG_ERROR, "Unable to load key file %s: %s\n",
265  c->key_file, ERR_error_string(ERR_get_error(), NULL));
266  ret = AVERROR(EIO);
267  goto fail;
268  }
269  // Note, this doesn't check that the peer certificate actually matches
270  // the requested hostname.
271  if (c->verify)
272  SSL_CTX_set_verify(p->ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
273  p->ssl = SSL_new(p->ctx);
274  if (!p->ssl) {
275  av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
276  ret = AVERROR(EIO);
277  goto fail;
278  }
279 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
280  p->url_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "urlprotocol bio");
281  BIO_meth_set_write(p->url_bio_method, url_bio_bwrite);
282  BIO_meth_set_read(p->url_bio_method, url_bio_bread);
283  BIO_meth_set_puts(p->url_bio_method, url_bio_bputs);
284  BIO_meth_set_ctrl(p->url_bio_method, url_bio_ctrl);
285  BIO_meth_set_create(p->url_bio_method, url_bio_create);
286  BIO_meth_set_destroy(p->url_bio_method, url_bio_destroy);
287  bio = BIO_new(p->url_bio_method);
288  BIO_set_data(bio, c->tcp);
289 #else
290  bio = BIO_new(&url_bio_method);
291  bio->ptr = c->tcp;
292 #endif
293  SSL_set_bio(p->ssl, bio, bio);
294  if (!c->listen && !c->numerichost)
295  SSL_set_tlsext_host_name(p->ssl, c->host);
296  ret = c->listen ? SSL_accept(p->ssl) : SSL_connect(p->ssl);
297  if (ret == 0) {
298  av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n");
299  ret = AVERROR(EIO);
300  goto fail;
301  } else if (ret < 0) {
302  ret = print_tls_error(h, ret);
303  goto fail;
304  }
305 
306  return 0;
307 fail:
308  tls_close(h);
309  return ret;
310 }
311 
312 static int tls_read(URLContext *h, uint8_t *buf, int size)
313 {
314  TLSContext *c = h->priv_data;
315  int ret;
316  // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
319  ret = SSL_read(c->ssl, buf, size);
320  if (ret > 0)
321  return ret;
322  if (ret == 0)
323  return AVERROR_EOF;
324  return print_tls_error(h, ret);
325 }
326 
327 static int tls_write(URLContext *h, const uint8_t *buf, int size)
328 {
329  TLSContext *c = h->priv_data;
330  int ret;
331  // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
334  ret = SSL_write(c->ssl, buf, size);
335  if (ret > 0)
336  return ret;
337  if (ret == 0)
338  return AVERROR_EOF;
339  return print_tls_error(h, ret);
340 }
341 
343 {
344  TLSContext *c = h->priv_data;
346 }
347 
348 static const AVOption options[] = {
349  TLS_COMMON_OPTIONS(TLSContext, tls_shared),
350  { NULL }
351 };
352 
353 static const AVClass tls_class = {
354  .class_name = "tls",
355  .item_name = av_default_item_name,
356  .option = options,
357  .version = LIBAVUTIL_VERSION_INT,
358 };
359 
361  .name = "tls",
362  .url_open2 = tls_open,
363  .url_read = tls_read,
364  .url_write = tls_write,
365  .url_close = tls_close,
366  .url_get_file_handle = tls_get_file_handle,
367  .priv_data_size = sizeof(TLSContext),
369  .priv_data_class = &tls_class,
370 };
#define NULL
Definition: coverity.c:32
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:108
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:421
static int url_bio_bwrite(BIO *b, const char *buf, int len)
Definition: tls_openssl.c:187
const char * b
Definition: vf_curves.c:116
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
Convenience header that includes libavutil's core.
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:173
uint8_t
AVOptions.
miscellaneous OS support macros and functions.
static int url_bio_bputs(BIO *b, const char *str)
Definition: tls_openssl.c:210
#define GET_BIO_DATA(x)
Definition: tls_openssl.c:170
Definition: tls.h:29
#define AVERROR_EOF
End of file.
Definition: error.h:55
ptrdiff_t size
Definition: opengl_enc.c:101
static int tls_get_file_handle(URLContext *h)
Definition: tls_openssl.c:342
#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:176
#define AVERROR(e)
Definition: error.h:43
Definition: graph2dot.c:48
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
Definition: tls_openssl.c:229
#define fail()
Definition: checkasm.h:117
char * host
Definition: tls.h:36
static const AVOption options[]
Definition: tls_openssl.c:348
void ff_openssl_deinit(void)
Definition: tls_openssl.c:99
static const AVClass tls_class
Definition: tls_openssl.c:353
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:100
char * cert_file
Definition: tls.h:32
static int tls_write(URLContext *h, const uint8_t *buf, int size)
Definition: tls_openssl.c:327
#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:626
#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:162
static int print_tls_error(URLContext *h, int ret)
Definition: tls_openssl.c:117
SSL_CTX * ctx
Definition: tls_openssl.c:44
#define AVIO_FLAG_NONBLOCK
Use non-blocking mode.
Definition: avio.h:673
int ff_openssl_init(void)
Definition: tls_openssl.c:69
TLSShared tls_shared
Definition: tls_gnutls.c:50
void * buf
Definition: avisynth_c.h:690
Definition: url.h:38
GLint GLenum type
Definition: opengl_enc.c:105
static int tls_read(URLContext *h, uint8_t *buf, int size)
Definition: tls_openssl.c:312
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:129
const URLProtocol ff_tls_protocol
Definition: tls_openssl.c:360
misc parsing utilities
const char * name
Definition: url.h:55
#define flags(name, subs,...)
Definition: cbs_av1.c:596
int ffurl_close(URLContext *h)
Definition: avio.c:467
Main libavformat public API header.
common internal api header.
_fmutex pthread_mutex_t
Definition: os2threads.h:49
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
static double c[64]
URLContext * tcp
Definition: tls.h:41
static BIO_METHOD url_bio_method
Definition: tls_openssl.c:216
int numerichost
Definition: tls.h:39
static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
Definition: tls_openssl.c:201
#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)
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:407
mode
Use these values in ebur128_init (or'ed).
Definition: ebur128.h:83
char * key_file
Definition: tls.h:33
static int url_bio_create(BIO *b)
Definition: tls_openssl.c:148