]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / Library / TlsAuthConfigLib / TlsAuthConfigLib.c
1 /** @file
2
3 A hook-in library for NetworkPkg/TlsAuthConfigDxe, in order to set volatile
4 variables related to TLS configuration, before TlsAuthConfigDxe or HttpDxe
5 (which is a UEFI_DRIVER) consume them.
6
7 Copyright (C) 2013, 2015, 2018, Red Hat, Inc.
8 Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
9
10 SPDX-License-Identifier: BSD-2-Clause-Patent
11
12 **/
13
14 #include <Uefi/UefiBaseType.h>
15 #include <Uefi/UefiSpec.h>
16
17 #include <Guid/HttpTlsCipherList.h>
18 #include <Guid/TlsAuthentication.h>
19
20 #include <Library/BaseLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/MemoryAllocationLib.h>
23 #include <Library/QemuFwCfgLib.h>
24 #include <Library/UefiRuntimeServicesTableLib.h>
25
26 /**
27 Read the list of trusted CA certificates from the fw_cfg file
28 "etc/edk2/https/cacerts", and store it to
29 gEfiTlsCaCertificateGuid:EFI_TLS_CA_CERTIFICATE_VARIABLE.
30
31 The contents are validated (for well-formedness) by NetworkPkg/HttpDxe.
32 **/
33 STATIC
34 VOID
35 SetCaCerts (
36 VOID
37 )
38 {
39 EFI_STATUS Status;
40 FIRMWARE_CONFIG_ITEM HttpsCaCertsItem;
41 UINTN HttpsCaCertsSize;
42 VOID *HttpsCaCerts;
43
44 Status = QemuFwCfgFindFile (
45 "etc/edk2/https/cacerts",
46 &HttpsCaCertsItem,
47 &HttpsCaCertsSize
48 );
49 if (EFI_ERROR (Status)) {
50 DEBUG ((
51 DEBUG_VERBOSE,
52 "%a:%a: not touching CA cert list\n",
53 gEfiCallerBaseName,
54 __FUNCTION__
55 ));
56 return;
57 }
58
59 //
60 // Delete the current EFI_TLS_CA_CERTIFICATE_VARIABLE if it exists. This
61 // serves two purposes:
62 //
63 // (a) If the variable exists with EFI_VARIABLE_NON_VOLATILE attribute, we
64 // cannot make it volatile without deleting it first.
65 //
66 // (b) If we fail to recreate the variable later, deleting the current one is
67 // still justified if the fw_cfg file exists. Emptying the set of trusted
68 // CA certificates will fail HTTPS boot, which is better than trusting
69 // any certificate that's possibly missing from the fw_cfg file.
70 //
71 Status = gRT->SetVariable (
72 EFI_TLS_CA_CERTIFICATE_VARIABLE, // VariableName
73 &gEfiTlsCaCertificateGuid, // VendorGuid
74 0, // Attributes
75 0, // DataSize
76 NULL // Data
77 );
78 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
79 //
80 // This is fatal.
81 //
82 DEBUG ((
83 DEBUG_ERROR,
84 "%a:%a: failed to delete %g:\"%s\"\n",
85 gEfiCallerBaseName,
86 __FUNCTION__,
87 &gEfiTlsCaCertificateGuid,
88 EFI_TLS_CA_CERTIFICATE_VARIABLE
89 ));
90 ASSERT_EFI_ERROR (Status);
91 CpuDeadLoop ();
92 }
93
94 if (HttpsCaCertsSize == 0) {
95 DEBUG ((
96 DEBUG_VERBOSE,
97 "%a:%a: applied empty CA cert list\n",
98 gEfiCallerBaseName,
99 __FUNCTION__
100 ));
101 return;
102 }
103
104 HttpsCaCerts = AllocatePool (HttpsCaCertsSize);
105 if (HttpsCaCerts == NULL) {
106 DEBUG ((
107 DEBUG_ERROR,
108 "%a:%a: failed to allocate HttpsCaCerts\n",
109 gEfiCallerBaseName,
110 __FUNCTION__
111 ));
112 return;
113 }
114
115 QemuFwCfgSelectItem (HttpsCaCertsItem);
116 QemuFwCfgReadBytes (HttpsCaCertsSize, HttpsCaCerts);
117
118 Status = gRT->SetVariable (
119 EFI_TLS_CA_CERTIFICATE_VARIABLE, // VariableName
120 &gEfiTlsCaCertificateGuid, // VendorGuid
121 EFI_VARIABLE_BOOTSERVICE_ACCESS, // Attributes
122 HttpsCaCertsSize, // DataSize
123 HttpsCaCerts // Data
124 );
125 if (EFI_ERROR (Status)) {
126 DEBUG ((
127 DEBUG_ERROR,
128 "%a:%a: failed to set %g:\"%s\": %r\n",
129 gEfiCallerBaseName,
130 __FUNCTION__,
131 &gEfiTlsCaCertificateGuid,
132 EFI_TLS_CA_CERTIFICATE_VARIABLE,
133 Status
134 ));
135 goto FreeHttpsCaCerts;
136 }
137
138 DEBUG ((
139 DEBUG_VERBOSE,
140 "%a:%a: stored CA cert list (%Lu byte(s))\n",
141 gEfiCallerBaseName,
142 __FUNCTION__,
143 (UINT64)HttpsCaCertsSize
144 ));
145
146 FreeHttpsCaCerts:
147 FreePool (HttpsCaCerts);
148 }
149
150 /**
151 Read the list of trusted cipher suites from the fw_cfg file
152 "etc/edk2/https/ciphers", and store it to
153 gEdkiiHttpTlsCipherListGuid:EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE.
154
155 The contents are propagated by NetworkPkg/HttpDxe to NetworkPkg/TlsDxe; the
156 list is processed by the latter.
157 **/
158 STATIC
159 VOID
160 SetCipherSuites (
161 VOID
162 )
163 {
164 EFI_STATUS Status;
165 FIRMWARE_CONFIG_ITEM HttpsCiphersItem;
166 UINTN HttpsCiphersSize;
167 VOID *HttpsCiphers;
168
169 Status = QemuFwCfgFindFile (
170 "etc/edk2/https/ciphers",
171 &HttpsCiphersItem,
172 &HttpsCiphersSize
173 );
174 if (EFI_ERROR (Status)) {
175 DEBUG ((
176 DEBUG_VERBOSE,
177 "%a:%a: not touching cipher suites\n",
178 gEfiCallerBaseName,
179 __FUNCTION__
180 ));
181 return;
182 }
183
184 //
185 // From this point on, any failure is fatal. An ordered cipher preference
186 // list is available from QEMU, thus we cannot let the firmware attempt HTTPS
187 // boot with either pre-existent or non-existent preferences. An empty set of
188 // cipher suites does not fail HTTPS boot automatically; the default cipher
189 // suite preferences would take effect, and we must prevent that.
190 //
191 // Delete the current EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE if it exists. If
192 // the variable exists with EFI_VARIABLE_NON_VOLATILE attribute, we cannot
193 // make it volatile without deleting it first.
194 //
195 Status = gRT->SetVariable (
196 EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE, // VariableName
197 &gEdkiiHttpTlsCipherListGuid, // VendorGuid
198 0, // Attributes
199 0, // DataSize
200 NULL // Data
201 );
202 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
203 DEBUG ((
204 DEBUG_ERROR,
205 "%a:%a: failed to delete %g:\"%s\"\n",
206 gEfiCallerBaseName,
207 __FUNCTION__,
208 &gEdkiiHttpTlsCipherListGuid,
209 EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE
210 ));
211 goto Done;
212 }
213
214 if (HttpsCiphersSize == 0) {
215 DEBUG ((
216 DEBUG_ERROR,
217 "%a:%a: list of cipher suites must not be empty\n",
218 gEfiCallerBaseName,
219 __FUNCTION__
220 ));
221 Status = EFI_INVALID_PARAMETER;
222 goto Done;
223 }
224
225 HttpsCiphers = AllocatePool (HttpsCiphersSize);
226 if (HttpsCiphers == NULL) {
227 DEBUG ((
228 DEBUG_ERROR,
229 "%a:%a: failed to allocate HttpsCiphers\n",
230 gEfiCallerBaseName,
231 __FUNCTION__
232 ));
233 Status = EFI_OUT_OF_RESOURCES;
234 goto Done;
235 }
236
237 QemuFwCfgSelectItem (HttpsCiphersItem);
238 QemuFwCfgReadBytes (HttpsCiphersSize, HttpsCiphers);
239
240 Status = gRT->SetVariable (
241 EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE, // VariableName
242 &gEdkiiHttpTlsCipherListGuid, // VendorGuid
243 EFI_VARIABLE_BOOTSERVICE_ACCESS, // Attributes
244 HttpsCiphersSize, // DataSize
245 HttpsCiphers // Data
246 );
247 if (EFI_ERROR (Status)) {
248 DEBUG ((
249 DEBUG_ERROR,
250 "%a:%a: failed to set %g:\"%s\"\n",
251 gEfiCallerBaseName,
252 __FUNCTION__,
253 &gEdkiiHttpTlsCipherListGuid,
254 EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE
255 ));
256 goto FreeHttpsCiphers;
257 }
258
259 DEBUG ((
260 DEBUG_VERBOSE,
261 "%a:%a: stored list of cipher suites (%Lu byte(s))\n",
262 gEfiCallerBaseName,
263 __FUNCTION__,
264 (UINT64)HttpsCiphersSize
265 ));
266
267 FreeHttpsCiphers:
268 FreePool (HttpsCiphers);
269
270 Done:
271 if (EFI_ERROR (Status)) {
272 ASSERT_EFI_ERROR (Status);
273 CpuDeadLoop ();
274 }
275 }
276
277 RETURN_STATUS
278 EFIAPI
279 TlsAuthConfigInit (
280 VOID
281 )
282 {
283 SetCaCerts ();
284 SetCipherSuites ();
285
286 return RETURN_SUCCESS;
287 }