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