UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / NetworkPkg / TlsAuthConfigDxe / TlsAuthConfigImpl.c
CommitLineData
7618784b
HW
1/** @file\r
2 The Miscellaneous Routines for TlsAuthConfigDxe driver.\r
3\r
f75a7f56 4Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
7618784b 5\r
ecf98fbc 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
7618784b
HW
7\r
8**/\r
9\r
10#include "TlsAuthConfigImpl.h"\r
11\r
d1050b9d
MK
12VOID *mStartOpCodeHandle = NULL;\r
13VOID *mEndOpCodeHandle = NULL;\r
14EFI_IFR_GUID_LABEL *mStartLabel = NULL;\r
15EFI_IFR_GUID_LABEL *mEndLabel = NULL;\r
7618784b 16\r
d1050b9d 17CHAR16 mTlsAuthConfigStorageName[] = L"TLS_AUTH_CONFIG_IFR_NVDATA";\r
7618784b 18\r
d1050b9d 19TLS_AUTH_CONFIG_PRIVATE_DATA *mTlsAuthPrivateData = NULL;\r
7618784b
HW
20\r
21HII_VENDOR_DEVICE_PATH mTlsAuthConfigHiiVendorDevicePath = {\r
22 {\r
23 {\r
24 HARDWARE_DEVICE_PATH,\r
25 HW_VENDOR_DP,\r
26 {\r
d1050b9d
MK
27 (UINT8)(sizeof (VENDOR_DEVICE_PATH)),\r
28 (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
7618784b
HW
29 }\r
30 },\r
31 TLS_AUTH_CONFIG_GUID\r
32 },\r
33 {\r
34 END_DEVICE_PATH_TYPE,\r
35 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
36 {\r
d1050b9d
MK
37 (UINT8)(END_DEVICE_PATH_LENGTH),\r
38 (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)\r
7618784b
HW
39 }\r
40 }\r
41};\r
42\r
43//\r
44// Possible DER-encoded certificate file suffixes, end with NULL pointer.\r
45//\r
d1050b9d 46CHAR16 *mDerPemEncodedSuffix[] = {\r
7618784b
HW
47 L".cer",\r
48 L".der",\r
49 L".crt",\r
50 L".pem",\r
51 NULL\r
52};\r
53\r
54/**\r
55 This code checks if the FileSuffix is one of the possible DER/PEM-encoded certificate suffix.\r
56\r
57 @param[in] FileSuffix The suffix of the input certificate file\r
58\r
59 @retval TRUE It's a DER/PEM-encoded certificate.\r
60 @retval FALSE It's NOT a DER/PEM-encoded certificate.\r
61\r
62**/\r
63BOOLEAN\r
64IsDerPemEncodeCertificate (\r
d1050b9d
MK
65 IN CONST CHAR16 *FileSuffix\r
66 )\r
7618784b 67{\r
d1050b9d
MK
68 UINTN Index;\r
69\r
7618784b
HW
70 for (Index = 0; mDerPemEncodedSuffix[Index] != NULL; Index++) {\r
71 if (StrCmp (FileSuffix, mDerPemEncodedSuffix[Index]) == 0) {\r
72 return TRUE;\r
73 }\r
74 }\r
d1050b9d 75\r
7618784b
HW
76 return FALSE;\r
77}\r
78\r
79/**\r
80 Worker function that prints an EFI_GUID into specified Buffer.\r
81\r
82 @param[in] Guid Pointer to GUID to print.\r
83 @param[in] Buffer Buffer to print Guid into.\r
84 @param[in] BufferSize Size of Buffer.\r
85\r
86 @retval Number of characters printed.\r
87\r
88**/\r
89UINTN\r
90GuidToString (\r
91 IN EFI_GUID *Guid,\r
92 IN CHAR16 *Buffer,\r
93 IN UINTN BufferSize\r
94 )\r
95{\r
96 return UnicodeSPrint (\r
97 Buffer,\r
98 BufferSize,\r
99 L"%g",\r
100 Guid\r
101 );\r
102}\r
103\r
104/**\r
105 List all cert in specified database by GUID in the page\r
106 for user to select and delete as needed.\r
107\r
108 @param[in] PrivateData Module's private data.\r
109 @param[in] VariableName The variable name of the vendor's signature database.\r
110 @param[in] VendorGuid A unique identifier for the vendor.\r
111 @param[in] LabelNumber Label number to insert opcodes.\r
112 @param[in] FormId Form ID of current page.\r
113 @param[in] QuestionIdBase Base question id of the signature list.\r
114\r
115 @retval EFI_SUCCESS Success to update the signature list page\r
116 @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.\r
117\r
118**/\r
119EFI_STATUS\r
120UpdateDeletePage (\r
d1050b9d
MK
121 IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,\r
122 IN CHAR16 *VariableName,\r
123 IN EFI_GUID *VendorGuid,\r
124 IN UINT16 LabelNumber,\r
125 IN EFI_FORM_ID FormId,\r
126 IN EFI_QUESTION_ID QuestionIdBase\r
7618784b
HW
127 )\r
128{\r
d1050b9d
MK
129 EFI_STATUS Status;\r
130 UINT32 Index;\r
131 UINTN CertCount;\r
132 UINTN GuidIndex;\r
133 VOID *StartOpCodeHandle;\r
134 VOID *EndOpCodeHandle;\r
135 EFI_IFR_GUID_LABEL *StartLabel;\r
136 EFI_IFR_GUID_LABEL *EndLabel;\r
137 UINTN DataSize;\r
138 UINT8 *Data;\r
139 EFI_SIGNATURE_LIST *CertList;\r
140 EFI_SIGNATURE_DATA *Cert;\r
141 UINT32 ItemDataSize;\r
142 CHAR16 *GuidStr;\r
143 EFI_STRING_ID GuidID;\r
144 EFI_STRING_ID Help;\r
145\r
146 Data = NULL;\r
147 CertList = NULL;\r
148 Cert = NULL;\r
149 GuidStr = NULL;\r
7618784b
HW
150 StartOpCodeHandle = NULL;\r
151 EndOpCodeHandle = NULL;\r
152\r
153 //\r
154 // Initialize the container for dynamic opcodes.\r
155 //\r
156 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
157 if (StartOpCodeHandle == NULL) {\r
158 Status = EFI_OUT_OF_RESOURCES;\r
159 goto ON_EXIT;\r
160 }\r
161\r
162 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
163 if (EndOpCodeHandle == NULL) {\r
164 Status = EFI_OUT_OF_RESOURCES;\r
165 goto ON_EXIT;\r
166 }\r
167\r
168 //\r
169 // Create Hii Extend Label OpCode.\r
170 //\r
d1050b9d
MK
171 StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (\r
172 StartOpCodeHandle,\r
173 &gEfiIfrTianoGuid,\r
174 NULL,\r
175 sizeof (EFI_IFR_GUID_LABEL)\r
176 );\r
177 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
178 StartLabel->Number = LabelNumber;\r
179\r
180 EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (\r
181 EndOpCodeHandle,\r
182 &gEfiIfrTianoGuid,\r
183 NULL,\r
184 sizeof (EFI_IFR_GUID_LABEL)\r
185 );\r
186 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
187 EndLabel->Number = LABEL_END;\r
7618784b
HW
188\r
189 //\r
190 // Read Variable.\r
191 //\r
192 DataSize = 0;\r
d1050b9d
MK
193 Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data);\r
194 if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {\r
7618784b
HW
195 goto ON_EXIT;\r
196 }\r
197\r
d1050b9d 198 Data = (UINT8 *)AllocateZeroPool (DataSize);\r
7618784b
HW
199 if (Data == NULL) {\r
200 Status = EFI_OUT_OF_RESOURCES;\r
201 goto ON_EXIT;\r
202 }\r
203\r
204 Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data);\r
205 if (EFI_ERROR (Status)) {\r
206 goto ON_EXIT;\r
207 }\r
208\r
209 GuidStr = AllocateZeroPool (100);\r
210 if (GuidStr == NULL) {\r
211 Status = EFI_OUT_OF_RESOURCES;\r
212 goto ON_EXIT;\r
213 }\r
214\r
215 //\r
216 // Enumerate all data.\r
217 //\r
d1050b9d
MK
218 ItemDataSize = (UINT32)DataSize;\r
219 CertList = (EFI_SIGNATURE_LIST *)Data;\r
220 GuidIndex = 0;\r
7618784b
HW
221\r
222 while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {\r
7618784b
HW
223 if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {\r
224 Help = STRING_TOKEN (STR_CERT_TYPE_PCKS_GUID);\r
225 } else {\r
226 //\r
227 // The signature type is not supported in current implementation.\r
228 //\r
229 ItemDataSize -= CertList->SignatureListSize;\r
d1050b9d 230 CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);\r
7618784b
HW
231 continue;\r
232 }\r
233\r
d1050b9d 234 CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
7618784b 235 for (Index = 0; Index < CertCount; Index++) {\r
d1050b9d
MK
236 Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList\r
237 + sizeof (EFI_SIGNATURE_LIST)\r
238 + CertList->SignatureHeaderSize\r
239 + Index * CertList->SignatureSize);\r
7618784b
HW
240 //\r
241 // Display GUID and help\r
242 //\r
243 GuidToString (&Cert->SignatureOwner, GuidStr, 100);\r
d1050b9d 244 GuidID = HiiSetString (Private->RegisteredHandle, 0, GuidStr, NULL);\r
7618784b
HW
245 HiiCreateCheckBoxOpCode (\r
246 StartOpCodeHandle,\r
d1050b9d 247 (EFI_QUESTION_ID)(QuestionIdBase + GuidIndex++),\r
7618784b
HW
248 0,\r
249 0,\r
250 GuidID,\r
251 Help,\r
252 EFI_IFR_FLAG_CALLBACK,\r
253 0,\r
254 NULL\r
255 );\r
256 }\r
257\r
258 ItemDataSize -= CertList->SignatureListSize;\r
d1050b9d 259 CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);\r
7618784b
HW
260 }\r
261\r
262ON_EXIT:\r
263 HiiUpdateForm (\r
264 Private->RegisteredHandle,\r
265 &gTlsAuthConfigGuid,\r
266 FormId,\r
267 StartOpCodeHandle,\r
268 EndOpCodeHandle\r
269 );\r
270\r
271 if (StartOpCodeHandle != NULL) {\r
272 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
273 }\r
274\r
275 if (EndOpCodeHandle != NULL) {\r
276 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
277 }\r
278\r
279 if (Data != NULL) {\r
280 FreePool (Data);\r
281 }\r
282\r
283 if (GuidStr != NULL) {\r
284 FreePool (GuidStr);\r
285 }\r
286\r
287 return EFI_SUCCESS;\r
288}\r
289\r
290/**\r
291 Delete one entry from cert database.\r
292\r
8ca41768 293 @param[in] Private Module's private data.\r
7618784b
HW
294 @param[in] VariableName The variable name of the database.\r
295 @param[in] VendorGuid A unique identifier for the vendor.\r
296 @param[in] LabelNumber Label number to insert opcodes.\r
297 @param[in] FormId Form ID of current page.\r
298 @param[in] QuestionIdBase Base question id of the cert list.\r
299 @param[in] DeleteIndex Cert index to delete.\r
300\r
dad13c80 301 @retval EFI_SUCCESS Delete signature successfully.\r
7618784b
HW
302 @retval EFI_NOT_FOUND Can't find the signature item,\r
303 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.\r
304**/\r
305EFI_STATUS\r
306DeleteCert (\r
d1050b9d
MK
307 IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,\r
308 IN CHAR16 *VariableName,\r
309 IN EFI_GUID *VendorGuid,\r
310 IN UINT16 LabelNumber,\r
311 IN EFI_FORM_ID FormId,\r
312 IN EFI_QUESTION_ID QuestionIdBase,\r
313 IN UINTN DeleteIndex\r
7618784b
HW
314 )\r
315{\r
d1050b9d
MK
316 EFI_STATUS Status;\r
317 UINTN DataSize;\r
318 UINT8 *Data;\r
319 UINT8 *OldData;\r
320 UINT32 Attr;\r
321 UINT32 Index;\r
322 EFI_SIGNATURE_LIST *CertList;\r
323 EFI_SIGNATURE_LIST *NewCertList;\r
324 EFI_SIGNATURE_DATA *Cert;\r
325 UINTN CertCount;\r
326 UINT32 Offset;\r
327 BOOLEAN IsItemFound;\r
328 UINT32 ItemDataSize;\r
329 UINTN GuidIndex;\r
330\r
331 Data = NULL;\r
332 OldData = NULL;\r
333 CertList = NULL;\r
334 Cert = NULL;\r
335 Attr = 0;\r
7618784b
HW
336\r
337 //\r
338 // Get original signature list data.\r
339 //\r
340 DataSize = 0;\r
d1050b9d
MK
341 Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, NULL);\r
342 if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {\r
7618784b
HW
343 goto ON_EXIT;\r
344 }\r
345\r
d1050b9d 346 OldData = (UINT8 *)AllocateZeroPool (DataSize);\r
7618784b
HW
347 if (OldData == NULL) {\r
348 Status = EFI_OUT_OF_RESOURCES;\r
349 goto ON_EXIT;\r
350 }\r
351\r
352 Status = gRT->GetVariable (VariableName, VendorGuid, &Attr, &DataSize, OldData);\r
d1050b9d 353 if (EFI_ERROR (Status)) {\r
7618784b
HW
354 goto ON_EXIT;\r
355 }\r
356\r
357 //\r
358 // Allocate space for new variable.\r
359 //\r
d1050b9d 360 Data = (UINT8 *)AllocateZeroPool (DataSize);\r
7618784b 361 if (Data == NULL) {\r
d1050b9d 362 Status = EFI_OUT_OF_RESOURCES;\r
7618784b
HW
363 goto ON_EXIT;\r
364 }\r
365\r
366 //\r
367 // Enumerate all data and erasing the target item.\r
368 //\r
d1050b9d
MK
369 IsItemFound = FALSE;\r
370 ItemDataSize = (UINT32)DataSize;\r
371 CertList = (EFI_SIGNATURE_LIST *)OldData;\r
372 Offset = 0;\r
373 GuidIndex = 0;\r
7618784b
HW
374 while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {\r
375 if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {\r
376 //\r
377 // Copy EFI_SIGNATURE_LIST header then calculate the signature count in this list.\r
378 //\r
d1050b9d
MK
379 CopyMem (Data + Offset, CertList, (sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize));\r
380 NewCertList = (EFI_SIGNATURE_LIST *)(Data + Offset);\r
381 Offset += (sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
382 Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
383 CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
7618784b
HW
384 for (Index = 0; Index < CertCount; Index++) {\r
385 if (GuidIndex == DeleteIndex) {\r
386 //\r
387 // Find it! Skip it!\r
388 //\r
389 NewCertList->SignatureListSize -= CertList->SignatureSize;\r
d1050b9d 390 IsItemFound = TRUE;\r
7618784b
HW
391 } else {\r
392 //\r
393 // This item doesn't match. Copy it to the Data buffer.\r
394 //\r
d1050b9d 395 CopyMem (Data + Offset, (UINT8 *)(Cert), CertList->SignatureSize);\r
7618784b
HW
396 Offset += CertList->SignatureSize;\r
397 }\r
d1050b9d 398\r
7618784b 399 GuidIndex++;\r
d1050b9d 400 Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);\r
7618784b
HW
401 }\r
402 } else {\r
403 //\r
404 // This List doesn't match. Just copy it to the Data buffer.\r
405 //\r
d1050b9d 406 CopyMem (Data + Offset, (UINT8 *)(CertList), CertList->SignatureListSize);\r
7618784b
HW
407 Offset += CertList->SignatureListSize;\r
408 }\r
409\r
410 ItemDataSize -= CertList->SignatureListSize;\r
d1050b9d 411 CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);\r
7618784b
HW
412 }\r
413\r
414 if (!IsItemFound) {\r
415 //\r
416 // Doesn't find the signature Item!\r
417 //\r
418 Status = EFI_NOT_FOUND;\r
419 goto ON_EXIT;\r
420 }\r
421\r
422 //\r
423 // Delete the EFI_SIGNATURE_LIST header if there is no signature in the list.\r
424 //\r
425 ItemDataSize = Offset;\r
d1050b9d
MK
426 CertList = (EFI_SIGNATURE_LIST *)Data;\r
427 Offset = 0;\r
7618784b
HW
428 ZeroMem (OldData, ItemDataSize);\r
429 while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {\r
d1050b9d 430 CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
7618784b
HW
431 DEBUG ((DEBUG_INFO, " CertCount = %x\n", CertCount));\r
432 if (CertCount != 0) {\r
d1050b9d 433 CopyMem (OldData + Offset, (UINT8 *)(CertList), CertList->SignatureListSize);\r
7618784b
HW
434 Offset += CertList->SignatureListSize;\r
435 }\r
d1050b9d 436\r
7618784b 437 ItemDataSize -= CertList->SignatureListSize;\r
d1050b9d 438 CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);\r
7618784b
HW
439 }\r
440\r
441 DataSize = Offset;\r
442\r
d1050b9d 443 Status = gRT->SetVariable (\r
7618784b
HW
444 VariableName,\r
445 VendorGuid,\r
446 Attr,\r
447 DataSize,\r
448 OldData\r
449 );\r
450 if (EFI_ERROR (Status)) {\r
451 DEBUG ((DEBUG_ERROR, "Failed to set variable, Status = %r\n", Status));\r
452 goto ON_EXIT;\r
453 }\r
454\r
455ON_EXIT:\r
456 if (Data != NULL) {\r
d1050b9d 457 FreePool (Data);\r
7618784b
HW
458 }\r
459\r
460 if (OldData != NULL) {\r
d1050b9d 461 FreePool (OldData);\r
7618784b
HW
462 }\r
463\r
464 return UpdateDeletePage (\r
465 Private,\r
466 VariableName,\r
467 VendorGuid,\r
468 LabelNumber,\r
469 FormId,\r
470 QuestionIdBase\r
471 );\r
472}\r
473\r
7618784b 474/**\r
8ca41768 475 Clean the file related resource.\r
7618784b 476\r
8ca41768 477 @param[in] Private Module's private data.\r
7618784b
HW
478\r
479**/\r
480VOID\r
8ca41768 481CleanFileContext (\r
d1050b9d 482 IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private\r
7618784b
HW
483 )\r
484{\r
8ca41768
JW
485 if (Private->FileContext->FHandle != NULL) {\r
486 Private->FileContext->FHandle->Close (Private->FileContext->FHandle);\r
487 Private->FileContext->FHandle = NULL;\r
d1050b9d
MK
488 if (Private->FileContext->FileName != NULL) {\r
489 FreePool (Private->FileContext->FileName);\r
8ca41768
JW
490 Private->FileContext->FileName = NULL;\r
491 }\r
7618784b
HW
492 }\r
493}\r
494\r
495/**\r
496 Read file content into BufferPtr, the size of the allocate buffer\r
497 is *FileSize plus AddtionAllocateSize.\r
498\r
499 @param[in] FileHandle The file to be read.\r
500 @param[in, out] BufferPtr Pointers to the pointer of allocated buffer.\r
501 @param[out] FileSize Size of input file\r
502 @param[in] AddtionAllocateSize Addtion size the buffer need to be allocated.\r
503 In case the buffer need to contain others besides the file content.\r
504\r
505 @retval EFI_SUCCESS The file was read into the buffer.\r
506 @retval EFI_INVALID_PARAMETER A parameter was invalid.\r
507 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
508 @retval others Unexpected error.\r
509\r
510**/\r
511EFI_STATUS\r
512ReadFileContent (\r
d1050b9d
MK
513 IN EFI_FILE_HANDLE FileHandle,\r
514 IN OUT VOID **BufferPtr,\r
515 OUT UINTN *FileSize,\r
516 IN UINTN AddtionAllocateSize\r
7618784b
HW
517 )\r
518\r
519{\r
d1050b9d
MK
520 UINTN BufferSize;\r
521 UINT64 SourceFileSize;\r
522 VOID *Buffer;\r
523 EFI_STATUS Status;\r
7618784b
HW
524\r
525 if ((FileHandle == NULL) || (FileSize == NULL)) {\r
526 return EFI_INVALID_PARAMETER;\r
527 }\r
528\r
529 Buffer = NULL;\r
530\r
531 //\r
532 // Get the file size\r
533 //\r
d1050b9d 534 Status = FileHandle->SetPosition (FileHandle, (UINT64)-1);\r
7618784b
HW
535 if (EFI_ERROR (Status)) {\r
536 goto ON_EXIT;\r
537 }\r
538\r
539 Status = FileHandle->GetPosition (FileHandle, &SourceFileSize);\r
540 if (EFI_ERROR (Status)) {\r
541 goto ON_EXIT;\r
542 }\r
543\r
544 Status = FileHandle->SetPosition (FileHandle, 0);\r
545 if (EFI_ERROR (Status)) {\r
546 goto ON_EXIT;\r
547 }\r
548\r
d1050b9d
MK
549 BufferSize = (UINTN)SourceFileSize + AddtionAllocateSize;\r
550 Buffer = AllocateZeroPool (BufferSize);\r
7618784b
HW
551 if (Buffer == NULL) {\r
552 return EFI_OUT_OF_RESOURCES;\r
553 }\r
554\r
d1050b9d 555 BufferSize = (UINTN)SourceFileSize;\r
7618784b
HW
556 *FileSize = BufferSize;\r
557\r
558 Status = FileHandle->Read (FileHandle, &BufferSize, Buffer);\r
d1050b9d 559 if (EFI_ERROR (Status) || (BufferSize != *FileSize)) {\r
7618784b
HW
560 FreePool (Buffer);\r
561 Buffer = NULL;\r
d1050b9d 562 Status = EFI_BAD_BUFFER_SIZE;\r
7618784b
HW
563 goto ON_EXIT;\r
564 }\r
565\r
566ON_EXIT:\r
567\r
568 *BufferPtr = Buffer;\r
569 return Status;\r
570}\r
571\r
7618784b
HW
572/**\r
573 This function converts an input device structure to a Unicode string.\r
574\r
575 @param[in] DevPath A pointer to the device path structure.\r
576\r
577 @return A new allocated Unicode string that represents the device path.\r
578\r
579**/\r
580CHAR16 *\r
581EFIAPI\r
582DevicePathToStr (\r
d1050b9d 583 IN EFI_DEVICE_PATH_PROTOCOL *DevPath\r
7618784b
HW
584 )\r
585{\r
586 return ConvertDevicePathToText (\r
587 DevPath,\r
588 FALSE,\r
589 TRUE\r
590 );\r
591}\r
592\r
7618784b
HW
593/**\r
594 Extract filename from device path. The returned buffer is allocated using AllocateCopyPool.\r
595 The caller is responsible for freeing the allocated buffer using FreePool(). If return NULL\r
596 means not enough memory resource.\r
597\r
598 @param DevicePath Device path.\r
599\r
dad13c80 600 @retval NULL Not enough memory resource for AllocateCopyPool.\r
7618784b
HW
601 @retval Other A new allocated string that represents the file name.\r
602\r
603**/\r
604CHAR16 *\r
605ExtractFileNameFromDevicePath (\r
d1050b9d 606 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
7618784b
HW
607 )\r
608{\r
d1050b9d
MK
609 CHAR16 *String;\r
610 CHAR16 *MatchString;\r
611 CHAR16 *LastMatch;\r
612 CHAR16 *FileName;\r
613 UINTN Length;\r
7618784b 614\r
d1050b9d 615 ASSERT (DevicePath != NULL);\r
7618784b 616\r
d1050b9d 617 String = DevicePathToStr (DevicePath);\r
7618784b
HW
618 MatchString = String;\r
619 LastMatch = String;\r
620 FileName = NULL;\r
621\r
d1050b9d 622 while (MatchString != NULL) {\r
7618784b 623 LastMatch = MatchString + 1;\r
d1050b9d 624 MatchString = StrStr (LastMatch, L"\\");\r
7618784b
HW
625 }\r
626\r
d1050b9d
MK
627 Length = StrLen (LastMatch);\r
628 FileName = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), LastMatch);\r
7618784b
HW
629 if (FileName != NULL) {\r
630 *(FileName + Length) = 0;\r
631 }\r
632\r
d1050b9d 633 FreePool (String);\r
7618784b
HW
634\r
635 return FileName;\r
636}\r
637\r
638/**\r
639 Enroll a new X509 certificate into Variable.\r
640\r
641 @param[in] PrivateData The module's private data.\r
642 @param[in] VariableName Variable name of CA database.\r
643\r
644 @retval EFI_SUCCESS New X509 is enrolled successfully.\r
645 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.\r
646\r
647**/\r
648EFI_STATUS\r
649EnrollX509toVariable (\r
d1050b9d
MK
650 IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,\r
651 IN CHAR16 *VariableName\r
7618784b
HW
652 )\r
653{\r
d1050b9d
MK
654 EFI_STATUS Status;\r
655 UINTN X509DataSize;\r
656 VOID *X509Data;\r
657 EFI_SIGNATURE_LIST *CACert;\r
658 EFI_SIGNATURE_DATA *CACertData;\r
659 VOID *Data;\r
660 UINTN DataSize;\r
661 UINTN SigDataSize;\r
662 UINT32 Attr;\r
663\r
664 X509DataSize = 0;\r
665 SigDataSize = 0;\r
666 DataSize = 0;\r
667 X509Data = NULL;\r
668 CACert = NULL;\r
669 CACertData = NULL;\r
670 Data = NULL;\r
671 Attr = 0;\r
7618784b
HW
672\r
673 Status = ReadFileContent (\r
674 Private->FileContext->FHandle,\r
675 &X509Data,\r
676 &X509DataSize,\r
677 0\r
678 );\r
679 if (EFI_ERROR (Status)) {\r
680 goto ON_EXIT;\r
681 }\r
d1050b9d 682\r
7618784b
HW
683 ASSERT (X509Data != NULL);\r
684\r
d1050b9d 685 SigDataSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize;\r
7618784b
HW
686\r
687 Data = AllocateZeroPool (SigDataSize);\r
688 if (Data == NULL) {\r
689 Status = EFI_OUT_OF_RESOURCES;\r
690 goto ON_EXIT;\r
691 }\r
692\r
693 //\r
694 // Fill Certificate Database parameters.\r
695 //\r
d1050b9d
MK
696 CACert = (EFI_SIGNATURE_LIST *)Data;\r
697 CACert->SignatureListSize = (UINT32)SigDataSize;\r
7618784b 698 CACert->SignatureHeaderSize = 0;\r
d1050b9d 699 CACert->SignatureSize = (UINT32)(sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize);\r
7618784b
HW
700 CopyGuid (&CACert->SignatureType, &gEfiCertX509Guid);\r
701\r
d1050b9d 702 CACertData = (EFI_SIGNATURE_DATA *)((UINT8 *)CACert + sizeof (EFI_SIGNATURE_LIST));\r
7618784b 703 CopyGuid (&CACertData->SignatureOwner, Private->CertGuid);\r
d1050b9d 704 CopyMem ((UINT8 *)(CACertData->SignatureData), X509Data, X509DataSize);\r
7618784b
HW
705\r
706 //\r
b90c335f
LE
707 // Check if the signature database entry already exists. If it does, use the\r
708 // EFI_VARIABLE_APPEND_WRITE attribute to append the new signature data to\r
709 // the original variable, plus preserve the original variable attributes.\r
7618784b 710 //\r
d1050b9d 711 Status = gRT->GetVariable (\r
7618784b
HW
712 VariableName,\r
713 &gEfiTlsCaCertificateGuid,\r
9bb1f080 714 &Attr,\r
7618784b
HW
715 &DataSize,\r
716 NULL\r
717 );\r
718 if (Status == EFI_BUFFER_TOO_SMALL) {\r
719 Attr |= EFI_VARIABLE_APPEND_WRITE;\r
b90c335f
LE
720 } else if (Status == EFI_NOT_FOUND) {\r
721 Attr = TLS_AUTH_CONFIG_VAR_BASE_ATTR;\r
722 } else {\r
7618784b
HW
723 goto ON_EXIT;\r
724 }\r
725\r
d1050b9d 726 Status = gRT->SetVariable (\r
7618784b
HW
727 VariableName,\r
728 &gEfiTlsCaCertificateGuid,\r
729 Attr,\r
730 SigDataSize,\r
731 Data\r
732 );\r
733 if (EFI_ERROR (Status)) {\r
734 goto ON_EXIT;\r
735 }\r
736\r
737ON_EXIT:\r
8ca41768 738 CleanFileContext (Private);\r
7618784b
HW
739\r
740 if (Private->CertGuid != NULL) {\r
741 FreePool (Private->CertGuid);\r
742 Private->CertGuid = NULL;\r
743 }\r
744\r
745 if (Data != NULL) {\r
746 FreePool (Data);\r
747 }\r
748\r
749 if (X509Data != NULL) {\r
750 FreePool (X509Data);\r
751 }\r
752\r
753 return Status;\r
754}\r
755\r
756/**\r
757 Enroll Cert into TlsCaCertificate. The GUID will be Private->CertGuid.\r
758\r
759 @param[in] PrivateData The module's private data.\r
760 @param[in] VariableName Variable name of signature database.\r
761\r
762 @retval EFI_SUCCESS New Cert enrolled successfully.\r
763 @retval EFI_INVALID_PARAMETER The parameter is invalid.\r
764 @retval EFI_UNSUPPORTED The Cert file is unsupported type.\r
765 @retval others Fail to enroll Cert data.\r
766\r
767**/\r
768EFI_STATUS\r
769EnrollCertDatabase (\r
770 IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,\r
771 IN CHAR16 *VariableName\r
772 )\r
773{\r
d1050b9d
MK
774 UINT16 *FilePostFix;\r
775 UINTN NameLength;\r
7618784b
HW
776\r
777 if ((Private->FileContext->FileName == NULL) || (Private->FileContext->FHandle == NULL) || (Private->CertGuid == NULL)) {\r
778 return EFI_INVALID_PARAMETER;\r
779 }\r
780\r
781 //\r
782 // Parse the file's postfix.\r
783 //\r
784 NameLength = StrLen (Private->FileContext->FileName);\r
785 if (NameLength <= 4) {\r
786 return EFI_INVALID_PARAMETER;\r
787 }\r
d1050b9d 788\r
7618784b
HW
789 FilePostFix = Private->FileContext->FileName + NameLength - 4;\r
790\r
791 if (IsDerPemEncodeCertificate (FilePostFix)) {\r
792 //\r
793 // Supports DER-encoded X509 certificate.\r
794 //\r
795 return EnrollX509toVariable (Private, VariableName);\r
796 }\r
797\r
798 return EFI_UNSUPPORTED;\r
799}\r
800\r
801/**\r
802 Refresh the global UpdateData structure.\r
803\r
804**/\r
805VOID\r
806RefreshUpdateData (\r
807 VOID\r
808 )\r
809{\r
810 //\r
811 // Free current updated date\r
812 //\r
813 if (mStartOpCodeHandle != NULL) {\r
814 HiiFreeOpCodeHandle (mStartOpCodeHandle);\r
815 }\r
816\r
817 //\r
818 // Create new OpCode Handle\r
819 //\r
820 mStartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
821\r
822 //\r
823 // Create Hii Extend Label OpCode as the start opcode\r
824 //\r
d1050b9d
MK
825 mStartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (\r
826 mStartOpCodeHandle,\r
827 &gEfiIfrTianoGuid,\r
828 NULL,\r
829 sizeof (EFI_IFR_GUID_LABEL)\r
830 );\r
7618784b
HW
831 mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
832}\r
833\r
834/**\r
835 Clean up the dynamic opcode at label and form specified by both LabelId.\r
836\r
837 @param[in] LabelId It is both the Form ID and Label ID for opcode deletion.\r
838 @param[in] PrivateData Module private data.\r
839\r
840**/\r
841VOID\r
842CleanUpPage (\r
d1050b9d
MK
843 IN UINT16 LabelId,\r
844 IN TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData\r
7618784b
HW
845 )\r
846{\r
847 RefreshUpdateData ();\r
848\r
849 //\r
850 // Remove all op-codes from dynamic page\r
851 //\r
852 mStartLabel->Number = LabelId;\r
853 HiiUpdateForm (\r
854 PrivateData->RegisteredHandle,\r
855 &gTlsAuthConfigGuid,\r
856 LabelId,\r
857 mStartOpCodeHandle, // Label LabelId\r
858 mEndOpCodeHandle // LABEL_END\r
859 );\r
860}\r
861\r
862/**\r
863 Update the form base on the selected file.\r
864\r
865 @param FilePath Point to the file path.\r
866 @param FormId The form need to display.\r
867\r
868 @retval TRUE Exit caller function.\r
869 @retval FALSE Not exit caller function.\r
870\r
871**/\r
872BOOLEAN\r
d1050b9d 873UpdatePage (\r
7618784b
HW
874 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,\r
875 IN EFI_FORM_ID FormId\r
876 )\r
877{\r
d1050b9d
MK
878 CHAR16 *FileName;\r
879 EFI_STRING_ID StringToken;\r
7618784b
HW
880\r
881 FileName = NULL;\r
882\r
883 if (FilePath != NULL) {\r
d1050b9d 884 FileName = ExtractFileNameFromDevicePath (FilePath);\r
7618784b 885 }\r
d1050b9d 886\r
7618784b
HW
887 if (FileName == NULL) {\r
888 //\r
889 // FileName = NULL has two case:\r
890 // 1. FilePath == NULL, not select file.\r
891 // 2. FilePath != NULL, but ExtractFileNameFromDevicePath return NULL not enough memory resource.\r
892 // In these two case, no need to update the form, and exit the caller function.\r
893 //\r
894 return TRUE;\r
895 }\r
d1050b9d 896\r
7618784b
HW
897 StringToken = HiiSetString (mTlsAuthPrivateData->RegisteredHandle, 0, FileName, NULL);\r
898\r
899 mTlsAuthPrivateData->FileContext->FileName = FileName;\r
900\r
9f5d1f7c 901 EfiOpenFileByDevicePath (\r
7618784b
HW
902 &FilePath,\r
903 &mTlsAuthPrivateData->FileContext->FHandle,\r
904 EFI_FILE_MODE_READ,\r
905 0\r
906 );\r
907 //\r
908 // Create Subtitle op-code for the display string of the option.\r
909 //\r
910 RefreshUpdateData ();\r
911 mStartLabel->Number = FormId;\r
912\r
913 HiiCreateSubTitleOpCode (\r
914 mStartOpCodeHandle,\r
915 StringToken,\r
916 0,\r
917 0,\r
918 0\r
d1050b9d 919 );\r
7618784b
HW
920\r
921 HiiUpdateForm (\r
922 mTlsAuthPrivateData->RegisteredHandle,\r
923 &gTlsAuthConfigGuid,\r
924 FormId,\r
925 mStartOpCodeHandle, /// Label FormId\r
926 mEndOpCodeHandle /// LABEL_END\r
927 );\r
928\r
929 return TRUE;\r
930}\r
931\r
932/**\r
933 Update the form base on the input file path info.\r
934\r
935 @param FilePath Point to the file path.\r
936\r
937 @retval TRUE Exit caller function.\r
938 @retval FALSE Not exit caller function.\r
939**/\r
940BOOLEAN\r
941EFIAPI\r
942UpdateCAFromFile (\r
d1050b9d 943 IN EFI_DEVICE_PATH_PROTOCOL *FilePath\r
7618784b
HW
944 )\r
945{\r
d1050b9d 946 return UpdatePage (FilePath, TLS_AUTH_CONFIG_FORMID4_FORM);\r
7618784b
HW
947}\r
948\r
949/**\r
950 Unload the configuration form, this includes: delete all the configuration\r
951 entries, uninstall the form callback protocol, and free the resources used.\r
952\r
953 @param[in] Private Pointer to the driver private data.\r
954\r
955 @retval EFI_SUCCESS The configuration form is unloaded.\r
956 @retval Others Failed to unload the form.\r
957\r
958**/\r
959EFI_STATUS\r
960TlsAuthConfigFormUnload (\r
d1050b9d 961 IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private\r
7618784b
HW
962 )\r
963{\r
964 if (Private->DriverHandle != NULL) {\r
965 //\r
966 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL\r
967 //\r
968 gBS->UninstallMultipleProtocolInterfaces (\r
969 Private->DriverHandle,\r
970 &gEfiDevicePathProtocolGuid,\r
971 &mTlsAuthConfigHiiVendorDevicePath,\r
972 &gEfiHiiConfigAccessProtocolGuid,\r
973 &Private->ConfigAccess,\r
974 NULL\r
975 );\r
976 Private->DriverHandle = NULL;\r
977 }\r
978\r
979 if (Private->RegisteredHandle != NULL) {\r
980 //\r
981 // Remove HII package list\r
982 //\r
983 HiiRemovePackages (Private->RegisteredHandle);\r
984 Private->RegisteredHandle = NULL;\r
985 }\r
986\r
987 if (Private->CertGuid != NULL) {\r
988 FreePool (Private->CertGuid);\r
989 }\r
990\r
991 if (Private->FileContext != NULL) {\r
992 FreePool (Private->FileContext);\r
993 }\r
994\r
995 FreePool (Private);\r
996\r
997 if (mStartOpCodeHandle != NULL) {\r
998 HiiFreeOpCodeHandle (mStartOpCodeHandle);\r
999 }\r
1000\r
1001 if (mEndOpCodeHandle != NULL) {\r
1002 HiiFreeOpCodeHandle (mEndOpCodeHandle);\r
1003 }\r
1004\r
1005 return EFI_SUCCESS;\r
1006}\r
1007\r
7618784b
HW
1008/**\r
1009 Initialize the configuration form.\r
1010\r
1011 @param[in] Private Pointer to the driver private data.\r
1012\r
1013 @retval EFI_SUCCESS The configuration form is initialized.\r
1014 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
1015\r
1016**/\r
1017EFI_STATUS\r
1018TlsAuthConfigFormInit (\r
d1050b9d 1019 IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private\r
7618784b
HW
1020 )\r
1021{\r
d1050b9d 1022 EFI_STATUS Status;\r
7618784b
HW
1023\r
1024 Private->Signature = TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE;\r
1025\r
1026 Private->ConfigAccess.ExtractConfig = TlsAuthConfigAccessExtractConfig;\r
1027 Private->ConfigAccess.RouteConfig = TlsAuthConfigAccessRouteConfig;\r
1028 Private->ConfigAccess.Callback = TlsAuthConfigAccessCallback;\r
1029\r
1030 //\r
1031 // Install Device Path Protocol and Config Access protocol to driver handle.\r
1032 //\r
1033 Status = gBS->InstallMultipleProtocolInterfaces (\r
1034 &Private->DriverHandle,\r
1035 &gEfiDevicePathProtocolGuid,\r
1036 &mTlsAuthConfigHiiVendorDevicePath,\r
1037 &gEfiHiiConfigAccessProtocolGuid,\r
1038 &Private->ConfigAccess,\r
1039 NULL\r
1040 );\r
1041 if (EFI_ERROR (Status)) {\r
1042 return Status;\r
1043 }\r
1044\r
1045 //\r
1046 // Publish our HII data.\r
1047 //\r
1048 Private->RegisteredHandle = HiiAddPackages (\r
1049 &gTlsAuthConfigGuid,\r
1050 Private->DriverHandle,\r
1051 TlsAuthConfigDxeStrings,\r
1052 TlsAuthConfigVfrBin,\r
1053 NULL\r
1054 );\r
1055 if (Private->RegisteredHandle == NULL) {\r
1056 Status = EFI_OUT_OF_RESOURCES;\r
1057 goto Error;\r
1058 }\r
1059\r
1060 Private->FileContext = AllocateZeroPool (sizeof (TLS_AUTH_CONFIG_FILE_CONTEXT));\r
1061 if (Private->FileContext == NULL) {\r
1062 Status = EFI_OUT_OF_RESOURCES;\r
1063 goto Error;\r
1064 }\r
1065\r
1066 //\r
1067 // Init OpCode Handle and Allocate space for creation of Buffer\r
1068 //\r
1069 mStartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1070 if (mStartOpCodeHandle == NULL) {\r
1071 Status = EFI_OUT_OF_RESOURCES;\r
1072 goto Error;\r
1073 }\r
1074\r
1075 mEndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1076 if (mEndOpCodeHandle == NULL) {\r
1077 Status = EFI_OUT_OF_RESOURCES;\r
1078 goto Error;\r
1079 }\r
1080\r
1081 //\r
1082 // Create Hii Extend Label OpCode as the start opcode\r
1083 //\r
d1050b9d
MK
1084 mStartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (\r
1085 mStartOpCodeHandle,\r
1086 &gEfiIfrTianoGuid,\r
1087 NULL,\r
1088 sizeof (EFI_IFR_GUID_LABEL)\r
1089 );\r
7618784b
HW
1090 mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1091\r
1092 //\r
1093 // Create Hii Extend Label OpCode as the end opcode\r
1094 //\r
d1050b9d
MK
1095 mEndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (\r
1096 mEndOpCodeHandle,\r
1097 &gEfiIfrTianoGuid,\r
1098 NULL,\r
1099 sizeof (EFI_IFR_GUID_LABEL)\r
1100 );\r
7618784b
HW
1101 mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1102 mEndLabel->Number = LABEL_END;\r
1103\r
1104 return EFI_SUCCESS;\r
1105\r
1106Error:\r
1107 TlsAuthConfigFormUnload (Private);\r
1108 return Status;\r
1109}\r
1110\r
1111/**\r
1112\r
1113 This function allows the caller to request the current\r
1114 configuration for one or more named elements. The resulting\r
1115 string is in <ConfigAltResp> format. Any and all alternative\r
1116 configuration strings shall also be appended to the end of the\r
1117 current configuration string. If they are, they must appear\r
1118 after the current configuration. They must contain the same\r
1119 routing (GUID, NAME, PATH) as the current configuration string.\r
1120 They must have an additional description indicating the type of\r
1121 alternative configuration the string represents,\r
1122 "ALTCFG=<StringToken>". That <StringToken> (when\r
1123 converted from Hex UNICODE to binary) is a reference to a\r
1124 string in the associated string pack.\r
1125\r
1126 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
1127\r
1128 @param Request A null-terminated Unicode string in\r
1129 <ConfigRequest> format. Note that this\r
1130 includes the routing information as well as\r
1131 the configurable name / value pairs. It is\r
1132 invalid for this string to be in\r
1133 <MultiConfigRequest> format.\r
1134 If a NULL is passed in for the Request field,\r
1135 all of the settings being abstracted by this function\r
1136 will be returned in the Results field. In addition,\r
1137 if a ConfigHdr is passed in with no request elements,\r
1138 all of the settings being abstracted for that particular\r
1139 ConfigHdr reference will be returned in the Results Field.\r
1140\r
1141 @param Progress On return, points to a character in the\r
1142 Request string. Points to the string's null\r
1143 terminator if request was successful. Points\r
1144 to the most recent "&" before the first\r
1145 failing name / value pair (or the beginning\r
1146 of the string if the failure is in the first\r
1147 name / value pair) if the request was not\r
1148 successful.\r
1149\r
1150 @param Results A null-terminated Unicode string in\r
1151 <MultiConfigAltResp> format which has all values\r
1152 filled in for the names in the Request string.\r
1153 String to be allocated by the called function.\r
1154\r
1155 @retval EFI_SUCCESS The Results string is filled with the\r
1156 values corresponding to all requested\r
1157 names.\r
1158\r
1159 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
1160 parts of the results that must be\r
1161 stored awaiting possible future\r
1162 protocols.\r
1163\r
1164 @retval EFI_NOT_FOUND Routing data doesn't match any\r
1165 known driver. Progress set to the\r
1166 first character in the routing header.\r
1167 Note: There is no requirement that the\r
1168 driver validate the routing data. It\r
1169 must skip the <ConfigHdr> in order to\r
1170 process the names.\r
1171\r
1172 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set\r
1173 to most recent "&" before the\r
1174 error or the beginning of the\r
1175 string.\r
1176\r
1177 @retval EFI_INVALID_PARAMETER Unknown name. Progress points\r
1178 to the & before the name in\r
1179 question.\r
1180\r
1181**/\r
1182EFI_STATUS\r
1183EFIAPI\r
1184TlsAuthConfigAccessExtractConfig (\r
1185 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1186 IN CONST EFI_STRING Request,\r
1187 OUT EFI_STRING *Progress,\r
1188 OUT EFI_STRING *Results\r
1189 )\r
1190{\r
d1050b9d
MK
1191 EFI_STATUS Status;\r
1192 UINTN BufferSize;\r
1193 UINTN Size;\r
1194 EFI_STRING ConfigRequest;\r
1195 EFI_STRING ConfigRequestHdr;\r
1196 TLS_AUTH_CONFIG_PRIVATE_DATA *Private;\r
1197 BOOLEAN AllocatedRequest;\r
1198\r
1199 if ((Progress == NULL) || (Results == NULL)) {\r
7618784b
HW
1200 return EFI_INVALID_PARAMETER;\r
1201 }\r
1202\r
1203 AllocatedRequest = FALSE;\r
1204 ConfigRequestHdr = NULL;\r
1205 ConfigRequest = NULL;\r
1206 Size = 0;\r
1207\r
d1050b9d 1208 Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);\r
7618784b 1209\r
d1050b9d 1210 BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);\r
7618784b
HW
1211 ZeroMem (&Private->TlsAuthConfigNvData, BufferSize);\r
1212\r
d1050b9d 1213 *Progress = Request;\r
7618784b
HW
1214\r
1215 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) {\r
1216 return EFI_NOT_FOUND;\r
1217 }\r
1218\r
1219 ConfigRequest = Request;\r
1220 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
1221 //\r
1222 // Request is set to NULL or OFFSET is NULL, construct full request string.\r
1223 //\r
1224 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
1225 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
1226 //\r
1227 ConfigRequestHdr = HiiConstructConfigHdr (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, Private->DriverHandle);\r
d1050b9d
MK
1228 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
1229 ConfigRequest = AllocateZeroPool (Size);\r
7618784b
HW
1230 ASSERT (ConfigRequest != NULL);\r
1231 AllocatedRequest = TRUE;\r
1232 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
1233 FreePool (ConfigRequestHdr);\r
1234 ConfigRequestHdr = NULL;\r
1235 }\r
1236\r
1237 Status = gHiiConfigRouting->BlockToConfig (\r
1238 gHiiConfigRouting,\r
1239 ConfigRequest,\r
d1050b9d 1240 (UINT8 *)&Private->TlsAuthConfigNvData,\r
7618784b
HW
1241 BufferSize,\r
1242 Results,\r
1243 Progress\r
1244 );\r
1245\r
1246 //\r
1247 // Free the allocated config request string.\r
1248 //\r
1249 if (AllocatedRequest) {\r
1250 FreePool (ConfigRequest);\r
1251 }\r
1252\r
1253 //\r
1254 // Set Progress string to the original request string.\r
1255 //\r
1256 if (Request == NULL) {\r
1257 *Progress = NULL;\r
1258 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
1259 *Progress = Request + StrLen (Request);\r
1260 }\r
1261\r
1262 return Status;\r
1263}\r
1264\r
1265/**\r
1266\r
1267 This function applies changes in a driver's configuration.\r
1268 Input is a Configuration, which has the routing data for this\r
1269 driver followed by name / value configuration pairs. The driver\r
1270 must apply those pairs to its configurable storage. If the\r
1271 driver's configuration is stored in a linear block of data\r
1272 and the driver's name / value pairs are in <BlockConfig>\r
1273 format, it may use the ConfigToBlock helper function (above) to\r
1274 simplify the job.\r
1275\r
1276 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
1277\r
1278 @param Configuration A null-terminated Unicode string in\r
1279 <ConfigString> format.\r
1280\r
1281 @param Progress A pointer to a string filled in with the\r
1282 offset of the most recent '&' before the\r
1283 first failing name / value pair (or the\r
dad13c80 1284 beginning of the string if the failure\r
7618784b
HW
1285 is in the first name / value pair) or\r
1286 the terminating NULL if all was\r
1287 successful.\r
1288\r
1289 @retval EFI_SUCCESS The results have been distributed or are\r
1290 awaiting distribution.\r
1291\r
1292 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
1293 parts of the results that must be\r
1294 stored awaiting possible future\r
1295 protocols.\r
1296\r
1297 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
1298 Results parameter would result\r
1299 in this type of error.\r
1300\r
1301 @retval EFI_NOT_FOUND Target for the specified routing data\r
1302 was not found\r
1303\r
1304**/\r
1305EFI_STATUS\r
1306EFIAPI\r
1307TlsAuthConfigAccessRouteConfig (\r
1308 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1309 IN CONST EFI_STRING Configuration,\r
1310 OUT EFI_STRING *Progress\r
1311 )\r
1312{\r
d1050b9d
MK
1313 EFI_STATUS Status;\r
1314 UINTN BufferSize;\r
1315 TLS_AUTH_CONFIG_PRIVATE_DATA *Private;\r
7618784b
HW
1316\r
1317 if (Progress == NULL) {\r
1318 return EFI_INVALID_PARAMETER;\r
1319 }\r
d1050b9d 1320\r
7618784b
HW
1321 *Progress = Configuration;\r
1322\r
1323 if (Configuration == NULL) {\r
1324 return EFI_INVALID_PARAMETER;\r
1325 }\r
1326\r
1327 //\r
1328 // Check routing data in <ConfigHdr>.\r
1329 // Note: there is no name for Name/Value storage, only GUID will be checked\r
1330 //\r
1331 if (!HiiIsConfigHdrMatch (Configuration, &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) {\r
1332 return EFI_NOT_FOUND;\r
1333 }\r
1334\r
1335 Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);\r
1336\r
1337 BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);\r
1338 ZeroMem (&Private->TlsAuthConfigNvData, BufferSize);\r
1339\r
1340 Status = gHiiConfigRouting->ConfigToBlock (\r
1341 gHiiConfigRouting,\r
1342 Configuration,\r
d1050b9d 1343 (UINT8 *)&Private->TlsAuthConfigNvData,\r
7618784b
HW
1344 &BufferSize,\r
1345 Progress\r
1346 );\r
1347 if (EFI_ERROR (Status)) {\r
1348 return Status;\r
1349 }\r
1350\r
1351 return Status;\r
1352}\r
1353\r
1354/**\r
1355\r
1356 This function is called to provide results data to the driver.\r
1357 This data consists of a unique key that is used to identify\r
1358 which data is either being passed back or being asked for.\r
1359\r
1360 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
1361 @param Action Specifies the type of action taken by the browser.\r
1362 @param QuestionId A unique value which is sent to the original\r
1363 exporting driver so that it can identify the type\r
1364 of data to expect. The format of the data tends to\r
1365 vary based on the opcode that generated the callback.\r
1366 @param Type The type of value for the question.\r
1367 @param Value A pointer to the data being sent to the original\r
1368 exporting driver.\r
1369 @param ActionRequest On return, points to the action requested by the\r
1370 callback function.\r
1371\r
1372 @retval EFI_SUCCESS The callback successfully handled the action.\r
1373 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
1374 variable and its data.\r
1375 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
1376 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
1377 callback.\r
1378**/\r
1379EFI_STATUS\r
1380EFIAPI\r
1381TlsAuthConfigAccessCallback (\r
d1050b9d
MK
1382 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1383 IN EFI_BROWSER_ACTION Action,\r
1384 IN EFI_QUESTION_ID QuestionId,\r
1385 IN UINT8 Type,\r
1386 IN OUT EFI_IFR_TYPE_VALUE *Value,\r
1387 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
7618784b
HW
1388 )\r
1389{\r
d1050b9d
MK
1390 EFI_STATUS Status;\r
1391 RETURN_STATUS RStatus;\r
1392 TLS_AUTH_CONFIG_PRIVATE_DATA *Private;\r
1393 UINTN BufferSize;\r
1394 TLS_AUTH_CONFIG_IFR_NVDATA *IfrNvData;\r
1395 UINT16 LabelId;\r
1396 EFI_DEVICE_PATH_PROTOCOL *File;\r
1397 EFI_HII_POPUP_PROTOCOL *HiiPopUp;\r
1398 EFI_HII_POPUP_SELECTION PopUpSelect;\r
1399\r
1400 Status = EFI_SUCCESS;\r
1401 File = NULL;\r
7618784b
HW
1402\r
1403 if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {\r
1404 return EFI_INVALID_PARAMETER;\r
1405 }\r
1406\r
1407 Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);\r
1408\r
1409 mTlsAuthPrivateData = Private;\r
d1050b9d 1410 Status = gBS->LocateProtocol (&gEfiHiiPopupProtocolGuid, NULL, (VOID **)&HiiPopUp);\r
ddfb0ab1
KC
1411 if (EFI_ERROR (Status)) {\r
1412 DEBUG ((DEBUG_ERROR, "Can't find Form PopUp protocol. Exit (%r)\n", Status));\r
1413 return Status;\r
1414 }\r
7618784b
HW
1415\r
1416 //\r
1417 // Retrieve uncommitted data from Browser\r
1418 //\r
1419 BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);\r
d1050b9d 1420 IfrNvData = AllocateZeroPool (BufferSize);\r
7618784b
HW
1421 if (IfrNvData == NULL) {\r
1422 return EFI_OUT_OF_RESOURCES;\r
1423 }\r
1424\r
d1050b9d 1425 HiiGetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, BufferSize, (UINT8 *)IfrNvData);\r
7618784b
HW
1426\r
1427 if ((Action != EFI_BROWSER_ACTION_CHANGED) &&\r
f75a7f56 1428 (Action != EFI_BROWSER_ACTION_CHANGING) &&\r
d1050b9d
MK
1429 (Action != EFI_BROWSER_ACTION_FORM_CLOSE))\r
1430 {\r
7618784b
HW
1431 Status = EFI_UNSUPPORTED;\r
1432 goto EXIT;\r
1433 }\r
1434\r
1435 if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
1436 switch (QuestionId) {\r
d1050b9d
MK
1437 case KEY_TLS_AUTH_CONFIG_CLIENT_CERT:\r
1438 case KEY_TLS_AUTH_CONFIG_SERVER_CA:\r
1439 //\r
1440 // Clear Cert GUID.\r
1441 //\r
1442 ZeroMem (IfrNvData->CertGuid, sizeof (IfrNvData->CertGuid));\r
7618784b 1443 if (Private->CertGuid == NULL) {\r
d1050b9d
MK
1444 Private->CertGuid = (EFI_GUID *)AllocateZeroPool (sizeof (EFI_GUID));\r
1445 if (Private->CertGuid == NULL) {\r
1446 return EFI_OUT_OF_RESOURCES;\r
1447 }\r
7618784b 1448 }\r
7618784b 1449\r
d1050b9d
MK
1450 if (QuestionId == KEY_TLS_AUTH_CONFIG_CLIENT_CERT) {\r
1451 LabelId = TLS_AUTH_CONFIG_FORMID3_FORM;\r
1452 } else {\r
1453 LabelId = TLS_AUTH_CONFIG_FORMID4_FORM;\r
1454 }\r
7618784b 1455\r
d1050b9d
MK
1456 //\r
1457 // Refresh selected file.\r
1458 //\r
1459 CleanUpPage (LabelId, Private);\r
1460 break;\r
1461 case KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE:\r
1462 //\r
1463 // If the file is already opened, clean the file related resource first.\r
1464 //\r
8ca41768
JW
1465 CleanFileContext (Private);\r
1466\r
d1050b9d
MK
1467 ChooseFile (NULL, NULL, UpdateCAFromFile, &File);\r
1468 break;\r
7618784b 1469\r
d1050b9d
MK
1470 case KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT:\r
1471 Status = EnrollCertDatabase (Private, EFI_TLS_CA_CERTIFICATE_VARIABLE);\r
1472 if (EFI_ERROR (Status)) {\r
1473 CleanFileContext (Private);\r
1474\r
1475 HiiPopUp->CreatePopup (\r
1476 HiiPopUp,\r
1477 EfiHiiPopupStyleError,\r
1478 EfiHiiPopupTypeOk,\r
1479 Private->RegisteredHandle,\r
1480 STRING_TOKEN (STR_TLS_AUTH_ENROLL_CERT_FAILURE),\r
1481 &PopUpSelect\r
1482 );\r
1483 }\r
7618784b 1484\r
d1050b9d
MK
1485 break;\r
1486\r
1487 case KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT:\r
1488 CleanFileContext (Private);\r
7618784b 1489\r
d1050b9d
MK
1490 if (Private->CertGuid != NULL) {\r
1491 FreePool (Private->CertGuid);\r
1492 Private->CertGuid = NULL;\r
1493 }\r
1494\r
1495 break;\r
1496\r
1497 case KEY_TLS_AUTH_CONFIG_DELETE_CERT:\r
1498 UpdateDeletePage (\r
7618784b
HW
1499 Private,\r
1500 EFI_TLS_CA_CERTIFICATE_VARIABLE,\r
1501 &gEfiTlsCaCertificateGuid,\r
1502 LABEL_CA_DELETE,\r
1503 TLS_AUTH_CONFIG_FORMID5_FORM,\r
d1050b9d 1504 OPTION_DEL_CA_ESTION_ID\r
7618784b 1505 );\r
d1050b9d
MK
1506 break;\r
1507\r
1508 default:\r
1509 if ((QuestionId >= OPTION_DEL_CA_ESTION_ID) &&\r
1510 (QuestionId < (OPTION_DEL_CA_ESTION_ID + OPTION_CONFIG_RANGE)))\r
1511 {\r
1512 DeleteCert (\r
1513 Private,\r
1514 EFI_TLS_CA_CERTIFICATE_VARIABLE,\r
1515 &gEfiTlsCaCertificateGuid,\r
1516 LABEL_CA_DELETE,\r
1517 TLS_AUTH_CONFIG_FORMID5_FORM,\r
1518 OPTION_DEL_CA_ESTION_ID,\r
1519 QuestionId - OPTION_DEL_CA_ESTION_ID\r
1520 );\r
1521 }\r
1522\r
1523 break;\r
7618784b
HW
1524 }\r
1525 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
1526 switch (QuestionId) {\r
d1050b9d
MK
1527 case KEY_TLS_AUTH_CONFIG_CERT_GUID:\r
1528 ASSERT (Private->CertGuid != NULL);\r
1529 RStatus = StrToGuid (\r
1530 IfrNvData->CertGuid,\r
1531 Private->CertGuid\r
1532 );\r
1533 if (RETURN_ERROR (RStatus) || (IfrNvData->CertGuid[GUID_STRING_LENGTH] != L'\0')) {\r
1534 Status = EFI_INVALID_PARAMETER;\r
1535 break;\r
1536 }\r
7618784b 1537\r
d1050b9d
MK
1538 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
1539 break;\r
1540 default:\r
1541 break;\r
7618784b 1542 }\r
8ca41768
JW
1543 } else if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) {\r
1544 CleanFileContext (Private);\r
7618784b
HW
1545 }\r
1546\r
1547EXIT:\r
1548\r
1549 if (!EFI_ERROR (Status)) {\r
1550 BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);\r
d1050b9d 1551 HiiSetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, BufferSize, (UINT8 *)IfrNvData, NULL);\r
7618784b
HW
1552 }\r
1553\r
1554 FreePool (IfrNvData);\r
1555\r
d1050b9d
MK
1556 if (File != NULL) {\r
1557 FreePool (File);\r
7618784b
HW
1558 File = NULL;\r
1559 }\r
1560\r
1561 return EFI_SUCCESS;\r
7618784b 1562}\r