Blame SOURCES/edk2-CryptoPkg-TlsLib-TlsSetVerifyHost-parse-IP-address-l.patch

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