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