audk/OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.c

226 lines
7.5 KiB
C
Raw Normal View History

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 0fd13678a681. 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>
2018-03-28 03:04:06 +02:00
/** @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>
SPDX-License-Identifier: BSD-2-Clause-Patent
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 0fd13678a681. 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>
2018-03-28 03:04:06 +02:00
**/
#include <Uefi/UefiBaseType.h>
#include <Uefi/UefiSpec.h>
#include <Guid/HttpTlsCipherList.h>
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 0fd13678a681. 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>
2018-03-28 03:04:06 +02:00
#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);
}
/**
Read the list of trusted cipher suites from the fw_cfg file
"etc/edk2/https/ciphers", and store it to
gEdkiiHttpTlsCipherListGuid:EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE.
The contents are propagated by NetworkPkg/HttpDxe to NetworkPkg/TlsDxe; the
list is processed by the latter.
**/
STATIC
VOID
SetCipherSuites (
VOID
)
{
EFI_STATUS Status;
FIRMWARE_CONFIG_ITEM HttpsCiphersItem;
UINTN HttpsCiphersSize;
VOID *HttpsCiphers;
Status = QemuFwCfgFindFile ("etc/edk2/https/ciphers", &HttpsCiphersItem,
&HttpsCiphersSize);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_VERBOSE, "%a:%a: not touching cipher suites\n",
gEfiCallerBaseName, __FUNCTION__));
return;
}
//
// From this point on, any failure is fatal. An ordered cipher preference
// list is available from QEMU, thus we cannot let the firmware attempt HTTPS
// boot with either pre-existent or non-existent preferences. An empty set of
// cipher suites does not fail HTTPS boot automatically; the default cipher
// suite preferences would take effect, and we must prevent that.
//
// Delete the current EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE if it exists. If
// the variable exists with EFI_VARIABLE_NON_VOLATILE attribute, we cannot
// make it volatile without deleting it first.
//
Status = gRT->SetVariable (
EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE, // VariableName
&gEdkiiHttpTlsCipherListGuid, // VendorGuid
0, // Attributes
0, // DataSize
NULL // Data
);
if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
DEBUG ((DEBUG_ERROR, "%a:%a: failed to delete %g:\"%s\"\n",
gEfiCallerBaseName, __FUNCTION__, &gEdkiiHttpTlsCipherListGuid,
EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE));
goto Done;
}
if (HttpsCiphersSize == 0) {
DEBUG ((DEBUG_ERROR, "%a:%a: list of cipher suites must not be empty\n",
gEfiCallerBaseName, __FUNCTION__));
Status = EFI_INVALID_PARAMETER;
goto Done;
}
HttpsCiphers = AllocatePool (HttpsCiphersSize);
if (HttpsCiphers == NULL) {
DEBUG ((DEBUG_ERROR, "%a:%a: failed to allocate HttpsCiphers\n",
gEfiCallerBaseName, __FUNCTION__));
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
QemuFwCfgSelectItem (HttpsCiphersItem);
QemuFwCfgReadBytes (HttpsCiphersSize, HttpsCiphers);
Status = gRT->SetVariable (
EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE, // VariableName
&gEdkiiHttpTlsCipherListGuid, // VendorGuid
EFI_VARIABLE_BOOTSERVICE_ACCESS, // Attributes
HttpsCiphersSize, // DataSize
HttpsCiphers // Data
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a:%a: failed to set %g:\"%s\"\n",
gEfiCallerBaseName, __FUNCTION__, &gEdkiiHttpTlsCipherListGuid,
EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE));
goto FreeHttpsCiphers;
}
DEBUG ((DEBUG_VERBOSE, "%a:%a: stored list of cipher suites (%Lu byte(s))\n",
gEfiCallerBaseName, __FUNCTION__, (UINT64)HttpsCiphersSize));
FreeHttpsCiphers:
FreePool (HttpsCiphers);
Done:
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
CpuDeadLoop ();
}
}
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 0fd13678a681. 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>
2018-03-28 03:04:06 +02:00
RETURN_STATUS
EFIAPI
TlsAuthConfigInit (
VOID
)
{
SetCaCerts ();
SetCipherSuites ();
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 0fd13678a681. 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>
2018-03-28 03:04:06 +02:00
return RETURN_SUCCESS;
}