1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * TLS/SSL Protocol 3cabdff1aSopenharmony_ci * Copyright (c) 2018 Thomas Volkert 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15cabdff1aSopenharmony_ci * Lesser General Public License for more details. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci */ 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci#include <mbedtls/version.h> 23cabdff1aSopenharmony_ci#include <mbedtls/ctr_drbg.h> 24cabdff1aSopenharmony_ci#include <mbedtls/entropy.h> 25cabdff1aSopenharmony_ci#include <mbedtls/net_sockets.h> 26cabdff1aSopenharmony_ci#include <mbedtls/platform.h> 27cabdff1aSopenharmony_ci#include <mbedtls/ssl.h> 28cabdff1aSopenharmony_ci#include <mbedtls/x509_crt.h> 29cabdff1aSopenharmony_ci 30cabdff1aSopenharmony_ci#include "avformat.h" 31cabdff1aSopenharmony_ci#include "internal.h" 32cabdff1aSopenharmony_ci#include "url.h" 33cabdff1aSopenharmony_ci#include "tls.h" 34cabdff1aSopenharmony_ci#include "libavutil/parseutils.h" 35cabdff1aSopenharmony_ci 36cabdff1aSopenharmony_citypedef struct TLSContext { 37cabdff1aSopenharmony_ci const AVClass *class; 38cabdff1aSopenharmony_ci TLSShared tls_shared; 39cabdff1aSopenharmony_ci mbedtls_ssl_context ssl_context; 40cabdff1aSopenharmony_ci mbedtls_ssl_config ssl_config; 41cabdff1aSopenharmony_ci mbedtls_entropy_context entropy_context; 42cabdff1aSopenharmony_ci mbedtls_ctr_drbg_context ctr_drbg_context; 43cabdff1aSopenharmony_ci mbedtls_x509_crt ca_cert; 44cabdff1aSopenharmony_ci mbedtls_x509_crt own_cert; 45cabdff1aSopenharmony_ci mbedtls_pk_context priv_key; 46cabdff1aSopenharmony_ci char *priv_key_pw; 47cabdff1aSopenharmony_ci} TLSContext; 48cabdff1aSopenharmony_ci 49cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(TLSContext, x) 50cabdff1aSopenharmony_ci 51cabdff1aSopenharmony_cistatic int tls_close(URLContext *h) 52cabdff1aSopenharmony_ci{ 53cabdff1aSopenharmony_ci TLSContext *tls_ctx = h->priv_data; 54cabdff1aSopenharmony_ci 55cabdff1aSopenharmony_ci mbedtls_ssl_close_notify(&tls_ctx->ssl_context); 56cabdff1aSopenharmony_ci mbedtls_pk_free(&tls_ctx->priv_key); 57cabdff1aSopenharmony_ci mbedtls_x509_crt_free(&tls_ctx->ca_cert); 58cabdff1aSopenharmony_ci mbedtls_x509_crt_free(&tls_ctx->own_cert); 59cabdff1aSopenharmony_ci mbedtls_ssl_free(&tls_ctx->ssl_context); 60cabdff1aSopenharmony_ci mbedtls_ssl_config_free(&tls_ctx->ssl_config); 61cabdff1aSopenharmony_ci mbedtls_ctr_drbg_free(&tls_ctx->ctr_drbg_context); 62cabdff1aSopenharmony_ci mbedtls_entropy_free(&tls_ctx->entropy_context); 63cabdff1aSopenharmony_ci 64cabdff1aSopenharmony_ci ffurl_closep(&tls_ctx->tls_shared.tcp); 65cabdff1aSopenharmony_ci return 0; 66cabdff1aSopenharmony_ci} 67cabdff1aSopenharmony_ci 68cabdff1aSopenharmony_cistatic int handle_transport_error(URLContext *h, const char* func_name, int react_on_eagain, int ret) 69cabdff1aSopenharmony_ci{ 70cabdff1aSopenharmony_ci switch (ret) { 71cabdff1aSopenharmony_ci case AVERROR(EAGAIN): 72cabdff1aSopenharmony_ci return react_on_eagain; 73cabdff1aSopenharmony_ci case AVERROR_EXIT: 74cabdff1aSopenharmony_ci return 0; 75cabdff1aSopenharmony_ci case AVERROR(EPIPE): 76cabdff1aSopenharmony_ci case AVERROR(ECONNRESET): 77cabdff1aSopenharmony_ci return MBEDTLS_ERR_NET_CONN_RESET; 78cabdff1aSopenharmony_ci default: 79cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "%s returned 0x%x\n", func_name, ret); 80cabdff1aSopenharmony_ci errno = EIO; 81cabdff1aSopenharmony_ci return MBEDTLS_ERR_NET_SEND_FAILED; 82cabdff1aSopenharmony_ci } 83cabdff1aSopenharmony_ci} 84cabdff1aSopenharmony_ci 85cabdff1aSopenharmony_cistatic int mbedtls_send(void *ctx, const unsigned char *buf, size_t len) 86cabdff1aSopenharmony_ci{ 87cabdff1aSopenharmony_ci URLContext *h = (URLContext*) ctx; 88cabdff1aSopenharmony_ci int ret = ffurl_write(h, buf, len); 89cabdff1aSopenharmony_ci if (ret >= 0) 90cabdff1aSopenharmony_ci return ret; 91cabdff1aSopenharmony_ci 92cabdff1aSopenharmony_ci if (h->max_packet_size && len > h->max_packet_size) 93cabdff1aSopenharmony_ci return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 94cabdff1aSopenharmony_ci 95cabdff1aSopenharmony_ci return handle_transport_error(h, "ffurl_write", MBEDTLS_ERR_SSL_WANT_WRITE, ret); 96cabdff1aSopenharmony_ci} 97cabdff1aSopenharmony_ci 98cabdff1aSopenharmony_cistatic int mbedtls_recv(void *ctx, unsigned char *buf, size_t len) 99cabdff1aSopenharmony_ci{ 100cabdff1aSopenharmony_ci URLContext *h = (URLContext*) ctx; 101cabdff1aSopenharmony_ci int ret = ffurl_read(h, buf, len); 102cabdff1aSopenharmony_ci if (ret >= 0) 103cabdff1aSopenharmony_ci return ret; 104cabdff1aSopenharmony_ci 105cabdff1aSopenharmony_ci if (h->max_packet_size && len > h->max_packet_size) 106cabdff1aSopenharmony_ci return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 107cabdff1aSopenharmony_ci 108cabdff1aSopenharmony_ci return handle_transport_error(h, "ffurl_read", MBEDTLS_ERR_SSL_WANT_READ, ret); 109cabdff1aSopenharmony_ci} 110cabdff1aSopenharmony_ci 111cabdff1aSopenharmony_cistatic void handle_pk_parse_error(URLContext *h, int ret) 112cabdff1aSopenharmony_ci{ 113cabdff1aSopenharmony_ci switch (ret) { 114cabdff1aSopenharmony_ci case MBEDTLS_ERR_PK_FILE_IO_ERROR: 115cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "Read of key file failed. Is it actually there, are the access permissions correct?\n"); 116cabdff1aSopenharmony_ci break; 117cabdff1aSopenharmony_ci case MBEDTLS_ERR_PK_PASSWORD_REQUIRED: 118cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "A password for the private key is missing.\n"); 119cabdff1aSopenharmony_ci break; 120cabdff1aSopenharmony_ci case MBEDTLS_ERR_PK_PASSWORD_MISMATCH: 121cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "The given password for the private key is wrong.\n"); 122cabdff1aSopenharmony_ci break; 123cabdff1aSopenharmony_ci default: 124cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "mbedtls_pk_parse_key returned -0x%x\n", -ret); 125cabdff1aSopenharmony_ci break; 126cabdff1aSopenharmony_ci } 127cabdff1aSopenharmony_ci} 128cabdff1aSopenharmony_ci 129cabdff1aSopenharmony_cistatic void handle_handshake_error(URLContext *h, int ret) 130cabdff1aSopenharmony_ci{ 131cabdff1aSopenharmony_ci switch (ret) { 132cabdff1aSopenharmony_ci#if MBEDTLS_VERSION_MAJOR < 3 133cabdff1aSopenharmony_ci case MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE: 134cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "None of the common ciphersuites is usable. Was the local certificate correctly set?\n"); 135cabdff1aSopenharmony_ci break; 136cabdff1aSopenharmony_ci#else 137cabdff1aSopenharmony_ci case MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE: 138cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "TLS handshake failed.\n"); 139cabdff1aSopenharmony_ci break; 140cabdff1aSopenharmony_ci#endif 141cabdff1aSopenharmony_ci case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE: 142cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "A fatal alert message was received from the peer, has the peer a correct certificate?\n"); 143cabdff1aSopenharmony_ci break; 144cabdff1aSopenharmony_ci case MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED: 145cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "No CA chain is set, but required to operate. Was the CA correctly set?\n"); 146cabdff1aSopenharmony_ci break; 147cabdff1aSopenharmony_ci case MBEDTLS_ERR_NET_CONN_RESET: 148cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "TLS handshake was aborted by peer.\n"); 149cabdff1aSopenharmony_ci break; 150cabdff1aSopenharmony_ci default: 151cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "mbedtls_ssl_handshake returned -0x%x\n", -ret); 152cabdff1aSopenharmony_ci break; 153cabdff1aSopenharmony_ci } 154cabdff1aSopenharmony_ci} 155cabdff1aSopenharmony_ci 156cabdff1aSopenharmony_cistatic void parse_options(TLSContext *tls_ctxc, const char *uri) 157cabdff1aSopenharmony_ci{ 158cabdff1aSopenharmony_ci char buf[1024]; 159cabdff1aSopenharmony_ci const char *p = strchr(uri, '?'); 160cabdff1aSopenharmony_ci if (!p) 161cabdff1aSopenharmony_ci return; 162cabdff1aSopenharmony_ci 163cabdff1aSopenharmony_ci if (!tls_ctxc->priv_key_pw && av_find_info_tag(buf, sizeof(buf), "key_password", p)) 164cabdff1aSopenharmony_ci tls_ctxc->priv_key_pw = av_strdup(buf); 165cabdff1aSopenharmony_ci} 166cabdff1aSopenharmony_ci 167cabdff1aSopenharmony_cistatic int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options) 168cabdff1aSopenharmony_ci{ 169cabdff1aSopenharmony_ci TLSContext *tls_ctx = h->priv_data; 170cabdff1aSopenharmony_ci TLSShared *shr = &tls_ctx->tls_shared; 171cabdff1aSopenharmony_ci uint32_t verify_res_flags; 172cabdff1aSopenharmony_ci int ret; 173cabdff1aSopenharmony_ci 174cabdff1aSopenharmony_ci // parse additional options 175cabdff1aSopenharmony_ci parse_options(tls_ctx, uri); 176cabdff1aSopenharmony_ci 177cabdff1aSopenharmony_ci if ((ret = ff_tls_open_underlying(shr, h, uri, options)) < 0) 178cabdff1aSopenharmony_ci goto fail; 179cabdff1aSopenharmony_ci 180cabdff1aSopenharmony_ci mbedtls_ssl_init(&tls_ctx->ssl_context); 181cabdff1aSopenharmony_ci mbedtls_ssl_config_init(&tls_ctx->ssl_config); 182cabdff1aSopenharmony_ci mbedtls_entropy_init(&tls_ctx->entropy_context); 183cabdff1aSopenharmony_ci mbedtls_ctr_drbg_init(&tls_ctx->ctr_drbg_context); 184cabdff1aSopenharmony_ci mbedtls_x509_crt_init(&tls_ctx->ca_cert); 185cabdff1aSopenharmony_ci mbedtls_pk_init(&tls_ctx->priv_key); 186cabdff1aSopenharmony_ci 187cabdff1aSopenharmony_ci // load trusted CA 188cabdff1aSopenharmony_ci if (shr->ca_file) { 189cabdff1aSopenharmony_ci if ((ret = mbedtls_x509_crt_parse_file(&tls_ctx->ca_cert, shr->ca_file)) != 0) { 190cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "mbedtls_x509_crt_parse_file for CA cert returned %d\n", ret); 191cabdff1aSopenharmony_ci goto fail; 192cabdff1aSopenharmony_ci } 193cabdff1aSopenharmony_ci } 194cabdff1aSopenharmony_ci 195cabdff1aSopenharmony_ci // load own certificate 196cabdff1aSopenharmony_ci if (shr->cert_file) { 197cabdff1aSopenharmony_ci if ((ret = mbedtls_x509_crt_parse_file(&tls_ctx->own_cert, shr->cert_file)) != 0) { 198cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "mbedtls_x509_crt_parse_file for own cert returned %d\n", ret); 199cabdff1aSopenharmony_ci goto fail; 200cabdff1aSopenharmony_ci } 201cabdff1aSopenharmony_ci } 202cabdff1aSopenharmony_ci 203cabdff1aSopenharmony_ci // seed the random number generator 204cabdff1aSopenharmony_ci if ((ret = mbedtls_ctr_drbg_seed(&tls_ctx->ctr_drbg_context, 205cabdff1aSopenharmony_ci mbedtls_entropy_func, 206cabdff1aSopenharmony_ci &tls_ctx->entropy_context, 207cabdff1aSopenharmony_ci NULL, 0)) != 0) { 208cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "mbedtls_ctr_drbg_seed returned %d\n", ret); 209cabdff1aSopenharmony_ci goto fail; 210cabdff1aSopenharmony_ci } 211cabdff1aSopenharmony_ci 212cabdff1aSopenharmony_ci // load key file 213cabdff1aSopenharmony_ci if (shr->key_file) { 214cabdff1aSopenharmony_ci if ((ret = mbedtls_pk_parse_keyfile(&tls_ctx->priv_key, 215cabdff1aSopenharmony_ci shr->key_file, 216cabdff1aSopenharmony_ci tls_ctx->priv_key_pw 217cabdff1aSopenharmony_ci#if MBEDTLS_VERSION_MAJOR >= 3 218cabdff1aSopenharmony_ci , mbedtls_ctr_drbg_random, 219cabdff1aSopenharmony_ci &tls_ctx->ctr_drbg_context 220cabdff1aSopenharmony_ci#endif 221cabdff1aSopenharmony_ci )) != 0) { 222cabdff1aSopenharmony_ci handle_pk_parse_error(h, ret); 223cabdff1aSopenharmony_ci goto fail; 224cabdff1aSopenharmony_ci } 225cabdff1aSopenharmony_ci } 226cabdff1aSopenharmony_ci 227cabdff1aSopenharmony_ci if ((ret = mbedtls_ssl_config_defaults(&tls_ctx->ssl_config, 228cabdff1aSopenharmony_ci shr->listen ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT, 229cabdff1aSopenharmony_ci MBEDTLS_SSL_TRANSPORT_STREAM, 230cabdff1aSopenharmony_ci MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { 231cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "mbedtls_ssl_config_defaults returned %d\n", ret); 232cabdff1aSopenharmony_ci goto fail; 233cabdff1aSopenharmony_ci } 234cabdff1aSopenharmony_ci 235cabdff1aSopenharmony_ci mbedtls_ssl_conf_authmode(&tls_ctx->ssl_config, 236cabdff1aSopenharmony_ci shr->verify ? MBEDTLS_SSL_VERIFY_REQUIRED : MBEDTLS_SSL_VERIFY_NONE); 237cabdff1aSopenharmony_ci mbedtls_ssl_conf_rng(&tls_ctx->ssl_config, mbedtls_ctr_drbg_random, &tls_ctx->ctr_drbg_context); 238cabdff1aSopenharmony_ci mbedtls_ssl_conf_ca_chain(&tls_ctx->ssl_config, &tls_ctx->ca_cert, NULL); 239cabdff1aSopenharmony_ci 240cabdff1aSopenharmony_ci // set own certificate and private key 241cabdff1aSopenharmony_ci if ((ret = mbedtls_ssl_conf_own_cert(&tls_ctx->ssl_config, &tls_ctx->own_cert, &tls_ctx->priv_key)) != 0) { 242cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "mbedtls_ssl_conf_own_cert returned %d\n", ret); 243cabdff1aSopenharmony_ci goto fail; 244cabdff1aSopenharmony_ci } 245cabdff1aSopenharmony_ci 246cabdff1aSopenharmony_ci if ((ret = mbedtls_ssl_setup(&tls_ctx->ssl_context, &tls_ctx->ssl_config)) != 0) { 247cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "mbedtls_ssl_setup returned %d\n", ret); 248cabdff1aSopenharmony_ci goto fail; 249cabdff1aSopenharmony_ci } 250cabdff1aSopenharmony_ci 251cabdff1aSopenharmony_ci if (!shr->listen && !shr->numerichost) { 252cabdff1aSopenharmony_ci if ((ret = mbedtls_ssl_set_hostname(&tls_ctx->ssl_context, shr->host)) != 0) { 253cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "mbedtls_ssl_set_hostname returned %d\n", ret); 254cabdff1aSopenharmony_ci goto fail; 255cabdff1aSopenharmony_ci } 256cabdff1aSopenharmony_ci } 257cabdff1aSopenharmony_ci 258cabdff1aSopenharmony_ci // set I/O functions to use FFmpeg internal code for transport layer 259cabdff1aSopenharmony_ci mbedtls_ssl_set_bio(&tls_ctx->ssl_context, shr->tcp, mbedtls_send, mbedtls_recv, NULL); 260cabdff1aSopenharmony_ci 261cabdff1aSopenharmony_ci // ssl handshake 262cabdff1aSopenharmony_ci while ((ret = mbedtls_ssl_handshake(&tls_ctx->ssl_context)) != 0) { 263cabdff1aSopenharmony_ci if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { 264cabdff1aSopenharmony_ci handle_handshake_error(h, ret); 265cabdff1aSopenharmony_ci goto fail; 266cabdff1aSopenharmony_ci } 267cabdff1aSopenharmony_ci } 268cabdff1aSopenharmony_ci 269cabdff1aSopenharmony_ci if (shr->verify) { 270cabdff1aSopenharmony_ci // check the result of the certificate verification 271cabdff1aSopenharmony_ci if ((verify_res_flags = mbedtls_ssl_get_verify_result(&tls_ctx->ssl_context)) != 0) { 272cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "mbedtls_ssl_get_verify_result reported problems "\ 273cabdff1aSopenharmony_ci "with the certificate verification, returned flags: %u\n", 274cabdff1aSopenharmony_ci verify_res_flags); 275cabdff1aSopenharmony_ci if (verify_res_flags & MBEDTLS_X509_BADCERT_NOT_TRUSTED) 276cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "The certificate is not correctly signed by the trusted CA.\n"); 277cabdff1aSopenharmony_ci goto fail; 278cabdff1aSopenharmony_ci } 279cabdff1aSopenharmony_ci } 280cabdff1aSopenharmony_ci 281cabdff1aSopenharmony_ci return 0; 282cabdff1aSopenharmony_ci 283cabdff1aSopenharmony_cifail: 284cabdff1aSopenharmony_ci tls_close(h); 285cabdff1aSopenharmony_ci return AVERROR(EIO); 286cabdff1aSopenharmony_ci} 287cabdff1aSopenharmony_ci 288cabdff1aSopenharmony_cistatic int handle_tls_error(URLContext *h, const char* func_name, int ret) 289cabdff1aSopenharmony_ci{ 290cabdff1aSopenharmony_ci switch (ret) { 291cabdff1aSopenharmony_ci case MBEDTLS_ERR_SSL_WANT_READ: 292cabdff1aSopenharmony_ci case MBEDTLS_ERR_SSL_WANT_WRITE: 293cabdff1aSopenharmony_ci return AVERROR(EAGAIN); 294cabdff1aSopenharmony_ci case MBEDTLS_ERR_NET_SEND_FAILED: 295cabdff1aSopenharmony_ci case MBEDTLS_ERR_NET_RECV_FAILED: 296cabdff1aSopenharmony_ci return AVERROR(EIO); 297cabdff1aSopenharmony_ci case MBEDTLS_ERR_NET_CONN_RESET: 298cabdff1aSopenharmony_ci case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: 299cabdff1aSopenharmony_ci av_log(h, AV_LOG_WARNING, "%s reported connection reset by peer\n", func_name); 300cabdff1aSopenharmony_ci return AVERROR_EOF; 301cabdff1aSopenharmony_ci default: 302cabdff1aSopenharmony_ci av_log(h, AV_LOG_ERROR, "%s returned -0x%x\n", func_name, -ret); 303cabdff1aSopenharmony_ci return AVERROR(EIO); 304cabdff1aSopenharmony_ci } 305cabdff1aSopenharmony_ci} 306cabdff1aSopenharmony_ci 307cabdff1aSopenharmony_cistatic int tls_read(URLContext *h, uint8_t *buf, int size) 308cabdff1aSopenharmony_ci{ 309cabdff1aSopenharmony_ci TLSContext *tls_ctx = h->priv_data; 310cabdff1aSopenharmony_ci int ret; 311cabdff1aSopenharmony_ci 312cabdff1aSopenharmony_ci if ((ret = mbedtls_ssl_read(&tls_ctx->ssl_context, buf, size)) > 0) { 313cabdff1aSopenharmony_ci // return read length 314cabdff1aSopenharmony_ci return ret; 315cabdff1aSopenharmony_ci } 316cabdff1aSopenharmony_ci 317cabdff1aSopenharmony_ci return handle_tls_error(h, "mbedtls_ssl_read", ret); 318cabdff1aSopenharmony_ci} 319cabdff1aSopenharmony_ci 320cabdff1aSopenharmony_cistatic int tls_write(URLContext *h, const uint8_t *buf, int size) 321cabdff1aSopenharmony_ci{ 322cabdff1aSopenharmony_ci TLSContext *tls_ctx = h->priv_data; 323cabdff1aSopenharmony_ci int ret; 324cabdff1aSopenharmony_ci 325cabdff1aSopenharmony_ci if ((ret = mbedtls_ssl_write(&tls_ctx->ssl_context, buf, size)) > 0) { 326cabdff1aSopenharmony_ci // return written length 327cabdff1aSopenharmony_ci return ret; 328cabdff1aSopenharmony_ci } 329cabdff1aSopenharmony_ci 330cabdff1aSopenharmony_ci return handle_tls_error(h, "mbedtls_ssl_write", ret); 331cabdff1aSopenharmony_ci} 332cabdff1aSopenharmony_ci 333cabdff1aSopenharmony_cistatic int tls_get_file_handle(URLContext *h) 334cabdff1aSopenharmony_ci{ 335cabdff1aSopenharmony_ci TLSContext *c = h->priv_data; 336cabdff1aSopenharmony_ci return ffurl_get_file_handle(c->tls_shared.tcp); 337cabdff1aSopenharmony_ci} 338cabdff1aSopenharmony_ci 339cabdff1aSopenharmony_cistatic int tls_get_short_seek(URLContext *h) 340cabdff1aSopenharmony_ci{ 341cabdff1aSopenharmony_ci TLSContext *s = h->priv_data; 342cabdff1aSopenharmony_ci return ffurl_get_short_seek(s->tls_shared.tcp); 343cabdff1aSopenharmony_ci} 344cabdff1aSopenharmony_ci 345cabdff1aSopenharmony_cistatic const AVOption options[] = { 346cabdff1aSopenharmony_ci TLS_COMMON_OPTIONS(TLSContext, tls_shared), \ 347cabdff1aSopenharmony_ci {"key_password", "Password for the private key file", OFFSET(priv_key_pw), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \ 348cabdff1aSopenharmony_ci { NULL } 349cabdff1aSopenharmony_ci}; 350cabdff1aSopenharmony_ci 351cabdff1aSopenharmony_cistatic const AVClass tls_class = { 352cabdff1aSopenharmony_ci .class_name = "tls", 353cabdff1aSopenharmony_ci .item_name = av_default_item_name, 354cabdff1aSopenharmony_ci .option = options, 355cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 356cabdff1aSopenharmony_ci}; 357cabdff1aSopenharmony_ci 358cabdff1aSopenharmony_ciconst URLProtocol ff_tls_protocol = { 359cabdff1aSopenharmony_ci .name = "tls", 360cabdff1aSopenharmony_ci .url_open2 = tls_open, 361cabdff1aSopenharmony_ci .url_read = tls_read, 362cabdff1aSopenharmony_ci .url_write = tls_write, 363cabdff1aSopenharmony_ci .url_close = tls_close, 364cabdff1aSopenharmony_ci .url_get_file_handle = tls_get_file_handle, 365cabdff1aSopenharmony_ci .url_get_short_seek = tls_get_short_seek, 366cabdff1aSopenharmony_ci .priv_data_size = sizeof(TLSContext), 367cabdff1aSopenharmony_ci .flags = URL_PROTOCOL_FLAG_NETWORK, 368cabdff1aSopenharmony_ci .priv_data_class = &tls_class, 369cabdff1aSopenharmony_ci}; 370