OvmfPkg/TlsAuthConfigLib: configure trusted CA certs for HTTPS boot

Introduce TlsAuthConfigLib to read the list of trusted CA certificates
from fw_cfg and to store it to EFI_TLS_CA_CERTIFICATE_VARIABLE.

The fw_cfg file is formatted by the "p11-kit" and "update-ca-trust"
utilities on the host side, so that the host settings take effect in guest
HTTPS boot as well. QEMU forwards the file intact to the firmware. The
contents are sanity-checked by NetworkPkg/HttpDxe code that was added in
commit 0fd13678a6.

Link TlsAuthConfigLib via NULL resolution into TlsAuthConfigDxe. This sets
EFI_TLS_CA_CERTIFICATE_VARIABLE in time for both
NetworkPkg/TlsAuthConfigDxe (for possible HII interaction with the user)
and for NetworkPkg/HttpDxe (for the effective TLS configuration).

The file formatted by "p11-kit" can be large. On a RHEL-7 host, the the
Mozilla CA root certificate bundle -- installed with the "ca-certificates"
package -- is processed into a 182KB file. Thus, create
EFI_TLS_CA_CERTIFICATE_VARIABLE as a volatile & boot-time only variable.
Also, in TLS_ENABLE builds, set the cumulative limit for volatile
variables (PcdVariableStoreSize) to 512KB, and the individual limit for
the same (PcdMaxVolatileVariableSize) to 256KB.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Gary Ching-Pang Lin <glin@suse.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Gary Lin <glin@suse.com>
Tested-by: Gary Lin <glin@suse.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
This commit is contained in:
Laszlo Ersek 2018-03-28 03:04:06 +02:00
parent c95e6d0917
commit 9c7d0d4992
5 changed files with 224 additions and 3 deletions

View File

@ -0,0 +1,133 @@
/** @file
A hook-in library for NetworkPkg/TlsAuthConfigDxe, in order to set volatile
variables related to TLS configuration, before TlsAuthConfigDxe or HttpDxe
(which is a UEFI_DRIVER) consume them.
Copyright (C) 2013, 2015, 2018, Red Hat, Inc.
Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Uefi/UefiBaseType.h>
#include <Uefi/UefiSpec.h>
#include <Guid/TlsAuthentication.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/QemuFwCfgLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
/**
Read the list of trusted CA certificates from the fw_cfg file
"etc/edk2/https/cacerts", and store it to
gEfiTlsCaCertificateGuid:EFI_TLS_CA_CERTIFICATE_VARIABLE.
The contents are validated (for well-formedness) by NetworkPkg/HttpDxe.
**/
STATIC
VOID
SetCaCerts (
VOID
)
{
EFI_STATUS Status;
FIRMWARE_CONFIG_ITEM HttpsCaCertsItem;
UINTN HttpsCaCertsSize;
VOID *HttpsCaCerts;
Status = QemuFwCfgFindFile ("etc/edk2/https/cacerts", &HttpsCaCertsItem,
&HttpsCaCertsSize);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_VERBOSE, "%a:%a: not touching CA cert list\n",
gEfiCallerBaseName, __FUNCTION__));
return;
}
//
// Delete the current EFI_TLS_CA_CERTIFICATE_VARIABLE if it exists. This
// serves two purposes:
//
// (a) If the variable exists with EFI_VARIABLE_NON_VOLATILE attribute, we
// cannot make it volatile without deleting it first.
//
// (b) If we fail to recreate the variable later, deleting the current one is
// still justified if the fw_cfg file exists. Emptying the set of trusted
// CA certificates will fail HTTPS boot, which is better than trusting
// any certificate that's possibly missing from the fw_cfg file.
//
Status = gRT->SetVariable (
EFI_TLS_CA_CERTIFICATE_VARIABLE, // VariableName
&gEfiTlsCaCertificateGuid, // VendorGuid
0, // Attributes
0, // DataSize
NULL // Data
);
if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
//
// This is fatal.
//
DEBUG ((DEBUG_ERROR, "%a:%a: failed to delete %g:\"%s\"\n",
gEfiCallerBaseName, __FUNCTION__, &gEfiTlsCaCertificateGuid,
EFI_TLS_CA_CERTIFICATE_VARIABLE));
ASSERT_EFI_ERROR (Status);
CpuDeadLoop ();
}
if (HttpsCaCertsSize == 0) {
DEBUG ((DEBUG_VERBOSE, "%a:%a: applied empty CA cert list\n",
gEfiCallerBaseName, __FUNCTION__));
return;
}
HttpsCaCerts = AllocatePool (HttpsCaCertsSize);
if (HttpsCaCerts == NULL) {
DEBUG ((DEBUG_ERROR, "%a:%a: failed to allocate HttpsCaCerts\n",
gEfiCallerBaseName, __FUNCTION__));
return;
}
QemuFwCfgSelectItem (HttpsCaCertsItem);
QemuFwCfgReadBytes (HttpsCaCertsSize, HttpsCaCerts);
Status = gRT->SetVariable (
EFI_TLS_CA_CERTIFICATE_VARIABLE, // VariableName
&gEfiTlsCaCertificateGuid, // VendorGuid
EFI_VARIABLE_BOOTSERVICE_ACCESS, // Attributes
HttpsCaCertsSize, // DataSize
HttpsCaCerts // Data
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a:%a: failed to set %g:\"%s\": %r\n",
gEfiCallerBaseName, __FUNCTION__, &gEfiTlsCaCertificateGuid,
EFI_TLS_CA_CERTIFICATE_VARIABLE, Status));
goto FreeHttpsCaCerts;
}
DEBUG ((DEBUG_VERBOSE, "%a:%a: stored CA cert list (%Lu byte(s))\n",
gEfiCallerBaseName, __FUNCTION__, (UINT64)HttpsCaCertsSize));
FreeHttpsCaCerts:
FreePool (HttpsCaCerts);
}
RETURN_STATUS
EFIAPI
TlsAuthConfigInit (
VOID
)
{
SetCaCerts ();
return RETURN_SUCCESS;
}

View File

@ -0,0 +1,55 @@
## @file
#
# A hook-in library for NetworkPkg/TlsAuthConfigDxe, in order to set volatile
# variables related to TLS configuration, before TlsAuthConfigDxe or HttpDxe
# (which is a UEFI_DRIVER) consume them.
#
# Copyright (C) 2013, 2015, 2018, Red Hat, Inc.
# Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are licensed and made available
# under the terms and conditions of the BSD License which accompanies this
# distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 1.26
BASE_NAME = TlsAuthConfigLib
FILE_GUID = 660AB627-4C5F-4D42-A3B6-BD021E9028BD
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = TlsAuthConfigLib|DXE_DRIVER
CONSTRUCTOR = TlsAuthConfigInit
#
# The following information is for reference only and not required by the build
# tools.
#
# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
#
[Sources]
TlsAuthConfigLib.c
[Packages]
MdePkg/MdePkg.dec
NetworkPkg/NetworkPkg.dec
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
BaseLib
DebugLib
MemoryAllocationLib
QemuFwCfgLib
UefiRuntimeServicesTableLib
[Guids]
gEfiTlsCaCertificateGuid ## PRODUCES ## Variable:L"TlsCaCertificate"
[Depex]
gEfiVariableWriteArchProtocolGuid

View File

@ -439,15 +439,23 @@
!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
!if $(TLS_ENABLE) == FALSE
# match PcdFlashNvStorageVariableSize purely for convenience
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000
!endif
!endif
!if $(FD_SIZE_IN_KB) == 4096
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x8400
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x8400
!if $(TLS_ENABLE) == FALSE
# match PcdFlashNvStorageVariableSize purely for convenience
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x40000
!endif
!endif
!if $(TLS_ENABLE) == TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x80000
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x40000
!endif
gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
@ -796,7 +804,10 @@
!endif
!if $(TLS_ENABLE) == TRUE
NetworkPkg/TlsDxe/TlsDxe.inf
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf {
<LibraryClasses>
NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf
}
!endif
OvmfPkg/VirtioNetDxe/VirtioNet.inf

View File

@ -444,15 +444,23 @@
!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
!if $(TLS_ENABLE) == FALSE
# match PcdFlashNvStorageVariableSize purely for convenience
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000
!endif
!endif
!if $(FD_SIZE_IN_KB) == 4096
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x8400
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x8400
!if $(TLS_ENABLE) == FALSE
# match PcdFlashNvStorageVariableSize purely for convenience
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x40000
!endif
!endif
!if $(TLS_ENABLE) == TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x80000
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x40000
!endif
gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
@ -805,7 +813,10 @@
!endif
!if $(TLS_ENABLE) == TRUE
NetworkPkg/TlsDxe/TlsDxe.inf
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf {
<LibraryClasses>
NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf
}
!endif
OvmfPkg/VirtioNetDxe/VirtioNet.inf

View File

@ -444,15 +444,23 @@
!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
!if $(TLS_ENABLE) == FALSE
# match PcdFlashNvStorageVariableSize purely for convenience
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000
!endif
!endif
!if $(FD_SIZE_IN_KB) == 4096
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x8400
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x8400
!if $(TLS_ENABLE) == FALSE
# match PcdFlashNvStorageVariableSize purely for convenience
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x40000
!endif
!endif
!if $(TLS_ENABLE) == TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x80000
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x40000
!endif
gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
@ -803,7 +811,10 @@
!endif
!if $(TLS_ENABLE) == TRUE
NetworkPkg/TlsDxe/TlsDxe.inf
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf {
<LibraryClasses>
NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf
}
!endif
OvmfPkg/VirtioNetDxe/VirtioNet.inf