3 * Copyright (c) 2011 Martin Storsjo
5 * This file is part of FFmpeg.
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.
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.
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
23 #include "os_support.h"
26 #include "libavutil/opt.h"
28 #include <openssl/bio.h>
29 #include <openssl/ssl.h>
30 #include <openssl/err.h>
32 typedef struct TLSContext
{
37 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
38 BIO_METHOD
* url_bio_method
;
43 /* OpenSSL 1.0.2 or below, then you would use SSL_library_init. If you are
44 * using OpenSSL 1.1.0 or above, then the library will initialize
45 * itself automatically.
46 * https://wiki.openssl.org/index.php/Library_Initialization
48 #if OPENSSL_VERSION_NUMBER < 0x10100000L
49 #include "libavutil/thread.h"
51 static AVMutex openssl_mutex
= AV_MUTEX_INITIALIZER
;
53 static int openssl_init
;
56 #include <openssl/crypto.h>
57 #include "libavutil/mem.h"
59 pthread_mutex_t
*openssl_mutexes
;
60 static void openssl_lock(int mode
, int type
, const char *file
, int line
)
62 if (mode
& CRYPTO_LOCK
)
63 pthread_mutex_lock(&openssl_mutexes
[type
]);
65 pthread_mutex_unlock(&openssl_mutexes
[type
]);
67 #if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000
68 static unsigned long openssl_thread_id(void)
70 return (intptr_t) pthread_self();
75 int ff_openssl_init(void)
77 ff_mutex_lock(&openssl_mutex
);
80 SSL_load_error_strings();
82 if (!CRYPTO_get_locking_callback()) {
84 openssl_mutexes
= av_malloc_array(sizeof(pthread_mutex_t
), CRYPTO_num_locks());
85 if (!openssl_mutexes
) {
86 ff_mutex_unlock(&openssl_mutex
);
87 return AVERROR(ENOMEM
);
90 for (i
= 0; i
< CRYPTO_num_locks(); i
++)
91 pthread_mutex_init(&openssl_mutexes
[i
], NULL
);
92 CRYPTO_set_locking_callback(openssl_lock
);
93 #if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000
94 CRYPTO_set_id_callback(openssl_thread_id
);
100 ff_mutex_unlock(&openssl_mutex
);
105 void ff_openssl_deinit(void)
107 ff_mutex_lock(&openssl_mutex
);
111 if (CRYPTO_get_locking_callback() == openssl_lock
) {
113 CRYPTO_set_locking_callback(NULL
);
114 for (i
= 0; i
< CRYPTO_num_locks(); i
++)
115 pthread_mutex_destroy(&openssl_mutexes
[i
]);
116 av_free(openssl_mutexes
);
120 ff_mutex_unlock(&openssl_mutex
);
124 static int print_tls_error(URLContext
*h
, int ret
)
126 TLSContext
*c
= h
->priv_data
;
127 int printed
= 0, e
, averr
= AVERROR(EIO
);
128 if (h
->flags
& AVIO_FLAG_NONBLOCK
) {
129 int err
= SSL_get_error(c
->ssl
, ret
);
130 if (err
== SSL_ERROR_WANT_READ
|| err
== SSL_ERROR_WANT_WRITE
)
131 return AVERROR(EAGAIN
);
133 while ((e
= ERR_get_error()) != 0) {
134 av_log(h
, AV_LOG_ERROR
, "%s\n", ERR_error_string(e
, NULL
));
138 av_log(h
, AV_LOG_ERROR
, "IO error: %s\n", av_err2str(c
->io_err
));
144 av_log(h
, AV_LOG_ERROR
, "Unknown error\n");
148 static int tls_close(URLContext
*h
)
150 TLSContext
*c
= h
->priv_data
;
152 SSL_shutdown(c
->ssl
);
156 SSL_CTX_free(c
->ctx
);
157 ffurl_closep(&c
->tls_shared
.tcp
);
158 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
159 if (c
->url_bio_method
)
160 BIO_meth_free(c
->url_bio_method
);
162 #if OPENSSL_VERSION_NUMBER < 0x10100000L
168 static int url_bio_create(BIO
*b
)
170 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
172 BIO_set_data(b
, NULL
);
182 static int url_bio_destroy(BIO
*b
)
187 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
188 #define GET_BIO_DATA(x) BIO_get_data(x)
190 #define GET_BIO_DATA(x) (x)->ptr
193 static int url_bio_bread(BIO
*b
, char *buf
, int len
)
195 TLSContext
*c
= GET_BIO_DATA(b
);
196 int ret
= ffurl_read(c
->tls_shared
.tcp
, buf
, len
);
199 BIO_clear_retry_flags(b
);
200 if (ret
== AVERROR_EXIT
)
202 if (ret
== AVERROR(EAGAIN
))
203 BIO_set_retry_read(b
);
209 static int url_bio_bwrite(BIO
*b
, const char *buf
, int len
)
211 TLSContext
*c
= GET_BIO_DATA(b
);
212 int ret
= ffurl_write(c
->tls_shared
.tcp
, buf
, len
);
215 BIO_clear_retry_flags(b
);
216 if (ret
== AVERROR_EXIT
)
218 if (ret
== AVERROR(EAGAIN
))
219 BIO_set_retry_write(b
);
225 static long url_bio_ctrl(BIO
*b
, int cmd
, long num
, void *ptr
)
227 if (cmd
== BIO_CTRL_FLUSH
) {
228 BIO_clear_retry_flags(b
);
234 static int url_bio_bputs(BIO
*b
, const char *str
)
236 return url_bio_bwrite(b
, str
, strlen(str
));
239 #if OPENSSL_VERSION_NUMBER < 0x1010000fL
240 static BIO_METHOD url_bio_method
= {
241 .type
= BIO_TYPE_SOURCE_SINK
,
242 .name
= "urlprotocol bio",
243 .bwrite
= url_bio_bwrite
,
244 .bread
= url_bio_bread
,
245 .bputs
= url_bio_bputs
,
247 .ctrl
= url_bio_ctrl
,
248 .create
= url_bio_create
,
249 .destroy
= url_bio_destroy
,
253 static int tls_open(URLContext
*h
, const char *uri
, int flags
, AVDictionary
**options
)
255 TLSContext
*p
= h
->priv_data
;
256 TLSShared
*c
= &p
->tls_shared
;
260 #if OPENSSL_VERSION_NUMBER < 0x10100000L
261 if ((ret
= ff_openssl_init()) < 0)
265 if ((ret
= ff_tls_open_underlying(c
, h
, uri
, options
)) < 0)
268 // We want to support all versions of TLS >= 1.0, but not the deprecated
269 // and insecure SSLv2 and SSLv3. Despite the name, SSLv23_*_method()
270 // enables support for all versions of SSL and TLS, and we then disable
271 // support for the old protocols immediately after creating the context.
272 p
->ctx
= SSL_CTX_new(c
->listen
? SSLv23_server_method() : SSLv23_client_method());
274 av_log(h
, AV_LOG_ERROR
, "%s\n", ERR_error_string(ERR_get_error(), NULL
));
278 SSL_CTX_set_options(p
->ctx
, SSL_OP_NO_SSLv2
| SSL_OP_NO_SSLv3
);
280 if (!SSL_CTX_load_verify_locations(p
->ctx
, c
->ca_file
, NULL
))
281 av_log(h
, AV_LOG_ERROR
, "SSL_CTX_load_verify_locations %s\n", ERR_error_string(ERR_get_error(), NULL
));
283 if (c
->cert_file
&& !SSL_CTX_use_certificate_chain_file(p
->ctx
, c
->cert_file
)) {
284 av_log(h
, AV_LOG_ERROR
, "Unable to load cert file %s: %s\n",
285 c
->cert_file
, ERR_error_string(ERR_get_error(), NULL
));
289 if (c
->key_file
&& !SSL_CTX_use_PrivateKey_file(p
->ctx
, c
->key_file
, SSL_FILETYPE_PEM
)) {
290 av_log(h
, AV_LOG_ERROR
, "Unable to load key file %s: %s\n",
291 c
->key_file
, ERR_error_string(ERR_get_error(), NULL
));
295 // Note, this doesn't check that the peer certificate actually matches
296 // the requested hostname.
298 SSL_CTX_set_verify(p
->ctx
, SSL_VERIFY_PEER
|SSL_VERIFY_FAIL_IF_NO_PEER_CERT
, NULL
);
299 p
->ssl
= SSL_new(p
->ctx
);
301 av_log(h
, AV_LOG_ERROR
, "%s\n", ERR_error_string(ERR_get_error(), NULL
));
305 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
306 p
->url_bio_method
= BIO_meth_new(BIO_TYPE_SOURCE_SINK
, "urlprotocol bio");
307 BIO_meth_set_write(p
->url_bio_method
, url_bio_bwrite
);
308 BIO_meth_set_read(p
->url_bio_method
, url_bio_bread
);
309 BIO_meth_set_puts(p
->url_bio_method
, url_bio_bputs
);
310 BIO_meth_set_ctrl(p
->url_bio_method
, url_bio_ctrl
);
311 BIO_meth_set_create(p
->url_bio_method
, url_bio_create
);
312 BIO_meth_set_destroy(p
->url_bio_method
, url_bio_destroy
);
313 bio
= BIO_new(p
->url_bio_method
);
314 BIO_set_data(bio
, p
);
316 bio
= BIO_new(&url_bio_method
);
319 SSL_set_bio(p
->ssl
, bio
, bio
);
320 if (!c
->listen
&& !c
->numerichost
)
321 SSL_set_tlsext_host_name(p
->ssl
, c
->host
);
322 ret
= c
->listen
? SSL_accept(p
->ssl
) : SSL_connect(p
->ssl
);
324 av_log(h
, AV_LOG_ERROR
, "Unable to negotiate TLS/SSL session\n");
327 } else if (ret
< 0) {
328 ret
= print_tls_error(h
, ret
);
338 static int tls_read(URLContext
*h
, uint8_t *buf
, int size
)
340 TLSContext
*c
= h
->priv_data
;
342 // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
343 c
->tls_shared
.tcp
->flags
&= ~AVIO_FLAG_NONBLOCK
;
344 c
->tls_shared
.tcp
->flags
|= h
->flags
& AVIO_FLAG_NONBLOCK
;
345 ret
= SSL_read(c
->ssl
, buf
, size
);
350 return print_tls_error(h
, ret
);
353 static int tls_write(URLContext
*h
, const uint8_t *buf
, int size
)
355 TLSContext
*c
= h
->priv_data
;
357 // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
358 c
->tls_shared
.tcp
->flags
&= ~AVIO_FLAG_NONBLOCK
;
359 c
->tls_shared
.tcp
->flags
|= h
->flags
& AVIO_FLAG_NONBLOCK
;
360 ret
= SSL_write(c
->ssl
, buf
, size
);
365 return print_tls_error(h
, ret
);
368 static int tls_get_file_handle(URLContext
*h
)
370 TLSContext
*c
= h
->priv_data
;
371 return ffurl_get_file_handle(c
->tls_shared
.tcp
);
374 static int tls_get_short_seek(URLContext
*h
)
376 TLSContext
*s
= h
->priv_data
;
377 return ffurl_get_short_seek(s
->tls_shared
.tcp
);
380 static const AVOption options
[] = {
381 TLS_COMMON_OPTIONS(TLSContext
, tls_shared
),
385 static const AVClass tls_class
= {
387 .item_name
= av_default_item_name
,
389 .version
= LIBAVUTIL_VERSION_INT
,
392 const URLProtocol ff_tls_protocol
= {
394 .url_open2
= tls_open
,
395 .url_read
= tls_read
,
396 .url_write
= tls_write
,
397 .url_close
= tls_close
,
398 .url_get_file_handle
= tls_get_file_handle
,
399 .url_get_short_seek
= tls_get_short_seek
,
400 .priv_data_size
= sizeof(TLSContext
),
401 .flags
= URL_PROTOCOL_FLAG_NETWORK
,
402 .priv_data_class
= &tls_class
,