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