|
|
6009e6 |
From 970b5f67512e00fb26765a14b4a1cb8a8a04276d Mon Sep 17 00:00:00 2001
|
|
|
6009e6 |
From: Laszlo Ersek <lersek@redhat.com>
|
|
|
6009e6 |
Date: Mon, 2 Dec 2019 12:31:57 +0100
|
|
|
6009e6 |
Subject: [PATCH 6/9] CryptoPkg/TlsLib: TlsSetVerifyHost: parse IP address
|
|
|
6009e6 |
literals as such (CVE-2019-14553)
|
|
|
6009e6 |
MIME-Version: 1.0
|
|
|
6009e6 |
Content-Type: text/plain; charset=UTF-8
|
|
|
6009e6 |
Content-Transfer-Encoding: 8bit
|
|
|
6009e6 |
|
|
|
6009e6 |
RH-Author: Laszlo Ersek <lersek@redhat.com>
|
|
|
6009e6 |
Message-id: <20191117220052.15700-7-lersek@redhat.com>
|
|
|
6009e6 |
Patchwork-id: 92452
|
|
|
6009e6 |
O-Subject: [RHEL-8.2.0 edk2 PATCH 6/9] CryptoPkg/TlsLib: TlsSetVerifyHost: parse IP address literals as such (CVE-2019-14553)
|
|
|
6009e6 |
Bugzilla: 1536624
|
|
|
6009e6 |
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
|
|
6009e6 |
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
|
|
6009e6 |
|
|
|
6009e6 |
Using the inet_pton() function that we imported in the previous patches,
|
|
|
6009e6 |
recognize if "HostName" is an IP address literal, and then parse it into
|
|
|
6009e6 |
binary representation. Passing the latter to OpenSSL for server
|
|
|
6009e6 |
certificate validation is important, per RFC-2818
|
|
|
6009e6 |
<https://tools.ietf.org/html/rfc2818#section-3.1>:
|
|
|
6009e6 |
|
|
|
6009e6 |
> In some cases, the URI is specified as an IP address rather than a
|
|
|
6009e6 |
> hostname. In this case, the iPAddress subjectAltName must be present in
|
|
|
6009e6 |
> the certificate and must exactly match the IP in the URI.
|
|
|
6009e6 |
|
|
|
6009e6 |
Note: we cannot use X509_VERIFY_PARAM_set1_ip_asc() because in the OpenSSL
|
|
|
6009e6 |
version that is currently consumed by edk2, said function depends on
|
|
|
6009e6 |
sscanf() for parsing IPv4 literals. In
|
|
|
6009e6 |
"CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c", we only provide an
|
|
|
6009e6 |
empty -- always failing -- stub for sscanf(), however.
|
|
|
6009e6 |
|
|
|
6009e6 |
Cc: David Woodhouse <dwmw2@infradead.org>
|
|
|
6009e6 |
Cc: Jian J Wang <jian.j.wang@intel.com>
|
|
|
6009e6 |
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
|
|
|
6009e6 |
Cc: Sivaraman Nainar <sivaramann@amiindia.co.in>
|
|
|
6009e6 |
Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
|
|
|
6009e6 |
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=960
|
|
|
6009e6 |
CVE: CVE-2019-14553
|
|
|
6009e6 |
Suggested-by: David Woodhouse <dwmw2@infradead.org>
|
|
|
6009e6 |
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
6009e6 |
Acked-by: Jian J Wang <jian.j.wang@intel.com>
|
|
|
6009e6 |
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
|
|
|
6009e6 |
(cherry picked from commit 1e72b1fb2ec597caedb5170079bb213f6d67f32a)
|
|
|
6009e6 |
---
|
|
|
6009e6 |
CryptoPkg/Library/TlsLib/TlsConfig.c | 28 ++++++++++++++++++++++++----
|
|
|
6009e6 |
1 file changed, 24 insertions(+), 4 deletions(-)
|
|
|
6009e6 |
|
|
|
6009e6 |
diff --git a/CryptoPkg/Library/TlsLib/TlsConfig.c b/CryptoPkg/Library/TlsLib/TlsConfig.c
|
|
|
6009e6 |
index 2bf5aee..307eb57 100644
|
|
|
6009e6 |
--- a/CryptoPkg/Library/TlsLib/TlsConfig.c
|
|
|
6009e6 |
+++ b/CryptoPkg/Library/TlsLib/TlsConfig.c
|
|
|
6009e6 |
@@ -517,7 +517,11 @@ TlsSetVerifyHost (
|
|
|
6009e6 |
IN CHAR8 *HostName
|
|
|
6009e6 |
)
|
|
|
6009e6 |
{
|
|
|
6009e6 |
- TLS_CONNECTION *TlsConn;
|
|
|
6009e6 |
+ TLS_CONNECTION *TlsConn;
|
|
|
6009e6 |
+ X509_VERIFY_PARAM *VerifyParam;
|
|
|
6009e6 |
+ UINTN BinaryAddressSize;
|
|
|
6009e6 |
+ UINT8 BinaryAddress[MAX (NS_INADDRSZ, NS_IN6ADDRSZ)];
|
|
|
6009e6 |
+ INTN ParamStatus;
|
|
|
6009e6 |
|
|
|
6009e6 |
TlsConn = (TLS_CONNECTION *) Tls;
|
|
|
6009e6 |
if (TlsConn == NULL || TlsConn->Ssl == NULL || HostName == NULL) {
|
|
|
6009e6 |
@@ -526,11 +530,27 @@ TlsSetVerifyHost (
|
|
|
6009e6 |
|
|
|
6009e6 |
SSL_set_hostflags(TlsConn->Ssl, Flags);
|
|
|
6009e6 |
|
|
|
6009e6 |
- if (SSL_set1_host(TlsConn->Ssl, HostName) == 0) {
|
|
|
6009e6 |
- return EFI_ABORTED;
|
|
|
6009e6 |
+ VerifyParam = SSL_get0_param (TlsConn->Ssl);
|
|
|
6009e6 |
+ ASSERT (VerifyParam != NULL);
|
|
|
6009e6 |
+
|
|
|
6009e6 |
+ BinaryAddressSize = 0;
|
|
|
6009e6 |
+ if (inet_pton (AF_INET6, HostName, BinaryAddress) == 1) {
|
|
|
6009e6 |
+ BinaryAddressSize = NS_IN6ADDRSZ;
|
|
|
6009e6 |
+ } else if (inet_pton (AF_INET, HostName, BinaryAddress) == 1) {
|
|
|
6009e6 |
+ BinaryAddressSize = NS_INADDRSZ;
|
|
|
6009e6 |
}
|
|
|
6009e6 |
|
|
|
6009e6 |
- return EFI_SUCCESS;
|
|
|
6009e6 |
+ if (BinaryAddressSize > 0) {
|
|
|
6009e6 |
+ DEBUG ((DEBUG_VERBOSE, "%a:%a: parsed \"%a\" as an IPv%c address "
|
|
|
6009e6 |
+ "literal\n", gEfiCallerBaseName, __FUNCTION__, HostName,
|
|
|
6009e6 |
+ (UINTN)((BinaryAddressSize == NS_IN6ADDRSZ) ? '6' : '4')));
|
|
|
6009e6 |
+ ParamStatus = X509_VERIFY_PARAM_set1_ip (VerifyParam, BinaryAddress,
|
|
|
6009e6 |
+ BinaryAddressSize);
|
|
|
6009e6 |
+ } else {
|
|
|
6009e6 |
+ ParamStatus = X509_VERIFY_PARAM_set1_host (VerifyParam, HostName, 0);
|
|
|
6009e6 |
+ }
|
|
|
6009e6 |
+
|
|
|
6009e6 |
+ return (ParamStatus == 1) ? EFI_SUCCESS : EFI_ABORTED;
|
|
|
6009e6 |
}
|
|
|
6009e6 |
|
|
|
6009e6 |
/**
|
|
|
6009e6 |
--
|
|
|
6009e6 |
1.8.3.1
|
|
|
6009e6 |
|