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