X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Ftls_openssl.c;h=178ca9e0e4684402cbcadfa5ab10136aceec4f76;hb=1bc6cdf2fcbd3caea7b78d0a617c6e338606d756;hp=46eb3e68c7e0a4aba1b76318137af8e9c3799bfb;hpb=3e5e5bdfef07526aa5c6b15e0484bdc51289cad9;p=ffmpeg diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c index 46eb3e68c7e..178ca9e0e46 100644 --- a/libavformat/tls_openssl.c +++ b/libavformat/tls_openssl.c @@ -43,6 +43,9 @@ typedef struct TLSContext { TLSShared tls_shared; SSL_CTX *ctx; SSL *ssl; +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + BIO_METHOD* url_bio_method; +#endif } TLSContext; #if HAVE_THREADS @@ -63,6 +66,87 @@ static unsigned long openssl_thread_id(void) #endif #endif +static int url_bio_create(BIO *b) +{ +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + BIO_set_init(b, 1); + BIO_set_data(b, NULL); + BIO_set_flags(b, 0); +#else + b->init = 1; + b->ptr = NULL; + b->flags = 0; +#endif + return 1; +} + +static int url_bio_destroy(BIO *b) +{ + return 1; +} + +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL +#define GET_BIO_DATA(x) BIO_get_data(x); +#else +#define GET_BIO_DATA(x) (x)->ptr; +#endif + +static int url_bio_bread(BIO *b, char *buf, int len) +{ + URLContext *h; + int ret; + h = GET_BIO_DATA(b); + ret = ffurl_read(h, buf, len); + if (ret >= 0) + return ret; + BIO_clear_retry_flags(b); + if (ret == AVERROR_EXIT) + return 0; + return -1; +} + +static int url_bio_bwrite(BIO *b, const char *buf, int len) +{ + URLContext *h; + int ret; + h = GET_BIO_DATA(b); + ret = ffurl_write(h, buf, len); + if (ret >= 0) + return ret; + BIO_clear_retry_flags(b); + if (ret == AVERROR_EXIT) + return 0; + return -1; +} + +static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + if (cmd == BIO_CTRL_FLUSH) { + BIO_clear_retry_flags(b); + return 1; + } + return 0; +} + +static int url_bio_bputs(BIO *b, const char *str) +{ + return url_bio_bwrite(b, str, strlen(str)); +} + +#if OPENSSL_VERSION_NUMBER < 0x1010000fL +static BIO_METHOD url_bio_method = { + .type = BIO_TYPE_SOURCE_SINK, + .name = "urlprotocol bio", + .bwrite = url_bio_bwrite, + .bread = url_bio_bread, + .bputs = url_bio_bputs, + .bgets = NULL, + .ctrl = url_bio_ctrl, + .create = url_bio_create, + .destroy = url_bio_destroy, +}; +#endif + int ff_openssl_init(void) { avpriv_lock_avformat(); @@ -128,73 +212,14 @@ static int tls_close(URLContext *h) SSL_CTX_free(c->ctx); if (c->tls_shared.tcp) ffurl_close(c->tls_shared.tcp); +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + if (c->url_bio_method) + BIO_meth_free(c->url_bio_method); +#endif ff_openssl_deinit(); return 0; } -static int url_bio_create(BIO *b) -{ - b->init = 1; - b->ptr = NULL; - b->flags = 0; - return 1; -} - -static int url_bio_destroy(BIO *b) -{ - return 1; -} - -static int url_bio_bread(BIO *b, char *buf, int len) -{ - URLContext *h = b->ptr; - int ret = ffurl_read(h, buf, len); - if (ret >= 0) - return ret; - BIO_clear_retry_flags(b); - if (ret == AVERROR_EXIT) - return 0; - return -1; -} - -static int url_bio_bwrite(BIO *b, const char *buf, int len) -{ - URLContext *h = b->ptr; - int ret = ffurl_write(h, buf, len); - if (ret >= 0) - return ret; - BIO_clear_retry_flags(b); - if (ret == AVERROR_EXIT) - return 0; - return -1; -} - -static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - if (cmd == BIO_CTRL_FLUSH) { - BIO_clear_retry_flags(b); - return 1; - } - return 0; -} - -static int url_bio_bputs(BIO *b, const char *str) -{ - return url_bio_bwrite(b, str, strlen(str)); -} - -static BIO_METHOD url_bio_method = { - .type = BIO_TYPE_SOURCE_SINK, - .name = "urlprotocol bio", - .bwrite = url_bio_bwrite, - .bread = url_bio_bread, - .bputs = url_bio_bputs, - .bgets = NULL, - .ctrl = url_bio_ctrl, - .create = url_bio_create, - .destroy = url_bio_destroy, -}; - static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options) { TLSContext *p = h->priv_data; @@ -208,12 +233,17 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0) goto fail; - p->ctx = SSL_CTX_new(c->listen ? TLSv1_server_method() : TLSv1_client_method()); + // We want to support all versions of TLS >= 1.0, but not the deprecated + // and insecure SSLv2 and SSLv3. Despite the name, SSLv23_*_method() + // enables support for all versions of SSL and TLS, and we then disable + // support for the old protocols immediately after creating the context. + p->ctx = SSL_CTX_new(c->listen ? SSLv23_server_method() : SSLv23_client_method()); if (!p->ctx) { av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL)); ret = AVERROR(EIO); goto fail; } + SSL_CTX_set_options(p->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); if (c->ca_file) { if (!SSL_CTX_load_verify_locations(p->ctx, c->ca_file, NULL)) av_log(h, AV_LOG_ERROR, "SSL_CTX_load_verify_locations %s\n", ERR_error_string(ERR_get_error(), NULL)); @@ -240,8 +270,20 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op ret = AVERROR(EIO); goto fail; } +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + p->url_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "urlprotocol bio"); + BIO_meth_set_write(p->url_bio_method, url_bio_bwrite); + BIO_meth_set_read(p->url_bio_method, url_bio_bread); + BIO_meth_set_puts(p->url_bio_method, url_bio_bputs); + BIO_meth_set_ctrl(p->url_bio_method, url_bio_ctrl); + BIO_meth_set_create(p->url_bio_method, url_bio_create); + BIO_meth_set_destroy(p->url_bio_method, url_bio_destroy); + bio = BIO_new(p->url_bio_method); + BIO_set_data(bio, c->tcp); +#else bio = BIO_new(&url_bio_method); bio->ptr = c->tcp; +#endif SSL_set_bio(p->ssl, bio, bio); if (!c->listen && !c->numerichost) SSL_set_tlsext_host_name(p->ssl, c->host);