From patchwork Wed Aug 16 07:19:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rodger Combs X-Patchwork-Id: 4720 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.46.211 with SMTP id u202csp455245vsu; Wed, 16 Aug 2017 00:28:03 -0700 (PDT) X-Received: by 10.223.128.46 with SMTP id 43mr576675wrk.246.1502868483386; Wed, 16 Aug 2017 00:28:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1502868483; cv=none; d=google.com; s=arc-20160816; b=mr3f4RUYoqe1T2wsyMtwfGTdlF0klEJgEIZrrEdipHwOwpsgK255dwYbDKF+LPGL6k bXYJ97s4f6+qge8Y1tXqPfc1HM7U5lwDbA6tq7/zi1cZ9oxXxZsenSKocqzx/DEIPUPJ RYWXAy7pD7HHXt1+0c2z+Y6oyqkrJLvB8JfIQuv7kjlZGSdcGYCVKTbsg7slAR+WlKd5 HrO7r0jB+sfNsGfC2BHmoeEDhA3dX98Yhk1ot7F0UDurM1FgGOG5LaH6CTRg8LLJsEui rbH8CZYq7lIZi+XM6Ajehp43cEWASrQ4LStnGfGpU8zWHHb8P2ZueR29sjPjPEjVy1kD X/bg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to:arc-authentication-results; bh=lKYsuldbvjOi5E1DgUSiWP6fe8WFN5ddZGDlPH1oJSM=; b=b5Im+o3DEPTK2Eoz5TRvroq7alRRfrYdGaAxmQalEugn5U9LxnYc1ICYOmw+8T87bL 4pWnt5UmKOqhnf8ROtk8Rmhru2DUfSXlqAE8wCTHiSn1CZRqBgoOX4wt2Em6ARn++BAU dEPJ+7OxYlqYAYi/3hEe7u3njRZ93w6Boc2WVWgihMNQjwFjMoUWBkV4Pu2dyf0kVUXz 4a1yUTt6q67js1eFVIzzPdID5cW2nvFrPvzLQ9kLXyPJsf/FJFJtajUVOLT5eFpWlGW0 PbV2tnoSYUxno2xgnld8AmL7ev402IodaaaAbQ45WsMABVZiI9iZMAdf1zQMbrnMex5N tW9w== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=rk2ny/r/; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id b58si195152wrb.338.2017.08.16.00.28.02; Wed, 16 Aug 2017 00:28:03 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=rk2ny/r/; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A6661689743; Wed, 16 Aug 2017 10:27:55 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-io0-f195.google.com (mail-io0-f195.google.com [209.85.223.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4434D689759 for ; Wed, 16 Aug 2017 10:27:49 +0300 (EEST) Received: by mail-io0-f195.google.com with SMTP id q64so1888636ioi.0 for ; Wed, 16 Aug 2017 00:27:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=d6W51IIz6jXS9s8NWOgT/NdM0eSl32N2PmfDX8rV0sc=; b=rk2ny/r/jvW4uTbuJl3ckVO2/LOM6/WX8UYQDYHoTmvQBokJXWubOiSttLZpYCQyRO O4U6KTLQwGkxIUFf+pi4qAevllcuZPlSkPcGeLCacs6Vy0EvJ4rb6b89bKVLPGYhDpYT 3oId+9eRle+RGsWyPH7SuX5mcNxMWCO90F7fSp6PxPJ1wayRFgvlgD+CQroCquIpZjpK 4axQkvR/fGSG1o1DuD00Up7igRRjmMsg6/Ze1g/de5sBtQ/i33PCsKgCZLQ8ZTSi/cej aBJDJdyDLayi0X3on3m0JzNaHDHN+e/GcYTiuFaoKLM30QXGjGyksAI1O9VWlyVJnxMa bXwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=d6W51IIz6jXS9s8NWOgT/NdM0eSl32N2PmfDX8rV0sc=; b=hE6AZkgpCyRkCEGqoMXMEcJEJclPJmOODTbgs9eshZkuw3rwIDPWq1vxIR7d6985WF 7zI08xz/RSpZzGNoc7KCHnCGcN7ca+oR+HGo0EP4C2sxnSEtmG9Fy4zajGGnviKWR2+1 zgky6Q+2ujD/z31HqO2uMq0GZI3+S4EjH03j7gkiqbKnTuSEwUZkSWhPgxTzHnpssEIP 93q07oc1qOHTLF7lwgY/1fFdAdR2cOOrSYJnsHG5QdJQ1ms8Yja9YjqC1XWdBkf6oJzs pvcBD2/Wst5b+fFBsqvlZ9T5fItTucyv6S/IQstalu6w+ZcltWSgNvDNetWrH3XytM9P mRWQ== X-Gm-Message-State: AHYfb5g0tQgV3KZ9LfPaKs9KWX4M74P6OJdPPgKTGvytQDHjkUskU6LA trXdRYlXLv4eb8i7h4I= X-Received: by 10.107.46.38 with SMTP id i38mr609310ioo.116.1502867967657; Wed, 16 Aug 2017 00:19:27 -0700 (PDT) Received: from Rodgers-MacBook-Pro.local.net (c-73-110-121-59.hsd1.il.comcast.net. [73.110.121.59]) by smtp.gmail.com with ESMTPSA id k12sm238377itk.29.2017.08.16.00.19.27 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 16 Aug 2017 00:19:27 -0700 (PDT) From: Rodger Combs To: ffmpeg-devel@ffmpeg.org Date: Wed, 16 Aug 2017 02:19:18 -0500 Message-Id: <20170816071918.98412-3-rodger.combs@gmail.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170816071918.98412-1-rodger.combs@gmail.com> References: <20170816071918.98412-1-rodger.combs@gmail.com> Subject: [FFmpeg-devel] [PATCH 3/3] lavf/tls: verify TLS connections by default whenever possible X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" This makes a reasonable effort to set the default configuration to behave securely, while maintaining the ability for consumers to produce builds using the old behavior without making changes to their runtime code. On Secure Transport and Secure Channel, we use a system-provided trust store, so we don't have to worry about providing our own. On OpenSSL and GNUTLS, we search for a default CA bundle path in the same locations as curl does in their configure script. If this fails (or the user disabled it by setting the path to an empty string), we turn off verification by default. The user can also set an explicit default CA path (which applies on any TLS engine), and explicitly enable or disable the new verify-by-default behavior. When verification is turned off at compile-time (as opposed to runtime), we log a warning indicating that this is the case, and informing the user of how they can turn on verification. Other options that were considered, but deemed too complex (for now) include: - Including a default trust store for OpenSSL and GNUTLS within the libavformat library, to be read from the build machine or fetched online at compile-time (a la nodejs). - Installing a library in the ffmpeg data directory, to be either copied from the build machine or fetched online at compile-time (a la curl). - Providing an "rpath"-style mechanism to set the default CA bundle path relative to the running executable. --- configure | 29 +++++++++++++++++++++++++++++ libavformat/tls.c | 15 +++++++++++++++ libavformat/tls.h | 6 +++--- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 7201941c36..aff5bf3bc7 100755 --- a/configure +++ b/configure @@ -374,6 +374,8 @@ Advanced options (experts only): disable buffer boundary checking in bitreaders (faster, but may crash) --sws-max-filter-size=N the max filter size swscale uses [$sws_max_filter_size_default] + --disable-tls-verify disable verifying TLS certificates by default [autodetect] + --ca-bundle-path=PATH path to the default trusted certificate authority list in PEM format [autodetect] Optimization options (experts only): --disable-asm disable all assembly optimizations @@ -1631,6 +1633,7 @@ FEATURE_LIST=" small static swscale_alpha + tls_verify " LIBRARY_LIST=" @@ -2200,6 +2203,7 @@ CMDLINE_SET=" build_suffix cc objcc + ca_bundle_path cpu cross_prefix custom_allocator @@ -6593,6 +6597,25 @@ enabled lavfi_indev && prepend avdevice_deps "avfilter" enabled opus_decoder && prepend avcodec_deps "swresample" +enabled_any tls_securetransport_protocol tls_schannel_protocol && enable_weak tls_verify +enabled_any tls_openssl_protocol tls_gnutls_protocol && test -z ${ca_bundle_path+x} && { + for file in /etc/ssl/certs/ca-certificates.crt \ + /etc/pki/tls/certs/ca-bundle.crt \ + /usr/share/ssl/certs/ca-bundle.crt \ + /usr/local/share/certs/ca-root-nss.crt \ + ${prefix}/share/certs/ca-root-nss.crt \ + /etc/ssl/cert.pem \ + ${prefix}/share/curl/curl-ca-bundle.crt \ + /usr/share/curl/curl-ca-bundle.crt \ + /usr/local/share/curl/curl-ca-bundle.crt; do + if test -f "$file"; then + ca_bundle_path="$file" + break + fi + done; +} +enabled_any tls_openssl_protocol tls_gnutls_protocol && test -n "${ca_bundle_path}" && enable_weak tls_verify + expand_deps(){ lib_deps=${1}_deps eval "deps=\$$lib_deps" @@ -6693,6 +6716,8 @@ echo "postprocessing support ${postproc-no}" echo "network support ${network-no}" echo "threading support ${thread_type-no}" echo "safe bitstream reader ${safe_bitstream_reader-no}" +echo "TLS cert verification ${tls_verify-no}" +echo "CA bundle path ${ca_bundle_path-none}" echo "texi2html enabled ${texi2html-no}" echo "perl enabled ${perl-no}" echo "pod2man enabled ${pod2man-no}" @@ -6909,6 +6934,10 @@ cat > $TMPH <>$TMPH || + echo "#define CA_BUNDLE_PATH NULL" >>$TMPH + test -n "$assert_level" && echo "#define ASSERT_LEVEL $assert_level" >>$TMPH diff --git a/libavformat/tls.c b/libavformat/tls.c index 10e0792e29..b1ce6529c8 100644 --- a/libavformat/tls.c +++ b/libavformat/tls.c @@ -64,6 +64,21 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV set_options(c, uri); + if (c->verify < 0) { + c->verify = CONFIG_TLS_VERIFY; +#if CONFIG_TLS_VERIFY == 0 + av_log(parent, AV_LOG_WARNING, "ffmpeg was configured without TLS verification enabled,\n" + "so this connection will be made insecurely.\n" + "To make this connection securely, enable the 'tls_verify' option%s" + ".\n", +#if (CONFIG_TLS_GNUTLS_PROTOCOL || CONFIG_TLS_OPENSSL_PROTOCOL) + (CA_BUNDLE_PATH == NULL) ? + "\nand specify a path to a trusted-root bundle with the 'ca_file' option" : +#endif + ""); +#endif + } + if (c->listen) snprintf(opts, sizeof(opts), "?listen=1"); diff --git a/libavformat/tls.h b/libavformat/tls.h index 53d0634f49..033d18c8db 100644 --- a/libavformat/tls.h +++ b/libavformat/tls.h @@ -45,9 +45,9 @@ typedef struct TLSShared { #define TLS_OPTFL (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM) #define TLS_COMMON_OPTIONS(pstruct, options_field) \ - {"ca_file", "Certificate Authority database file", offsetof(pstruct, options_field . ca_file), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \ - {"cafile", "Certificate Authority database file", offsetof(pstruct, options_field . ca_file), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \ - {"tls_verify", "Verify the peer certificate", offsetof(pstruct, options_field . verify), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = TLS_OPTFL }, \ + {"ca_file", "Certificate Authority database file", offsetof(pstruct, options_field . ca_file), AV_OPT_TYPE_STRING, { .str = CA_BUNDLE_PATH }, .flags = TLS_OPTFL }, \ + {"cafile", "Certificate Authority database file", offsetof(pstruct, options_field . ca_file), AV_OPT_TYPE_STRING, { .str = CA_BUNDLE_PATH }, .flags = TLS_OPTFL }, \ + {"tls_verify", "Verify the peer certificate", offsetof(pstruct, options_field . verify), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags = TLS_OPTFL }, \ {"cert_file", "Certificate file", offsetof(pstruct, options_field . cert_file), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \ {"key_file", "Private key file", offsetof(pstruct, options_field . key_file), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \ {"listen", "Listen for incoming connections", offsetof(pstruct, options_field . listen), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = TLS_OPTFL }, \