]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c
715bc3a0a9414912e55307ffcc609cbe2b69a412
[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 VOID *CurrentData;
661 UINTN DataSize;
662 UINTN SigDataSize;
663 UINT32 Attr;
664
665 X509DataSize = 0;
666 SigDataSize = 0;
667 DataSize = 0;
668 X509Data = NULL;
669 CACert = NULL;
670 CACertData = NULL;
671 Data = NULL;
672 CurrentData = NULL;
673 Attr = 0;
674
675 Status = ReadFileContent (
676 Private->FileContext->FHandle,
677 &X509Data,
678 &X509DataSize,
679 0
680 );
681 if (EFI_ERROR (Status)) {
682 goto ON_EXIT;
683 }
684 ASSERT (X509Data != NULL);
685
686 SigDataSize = sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_SIGNATURE_DATA) - 1 + X509DataSize;
687
688 Data = AllocateZeroPool (SigDataSize);
689 if (Data == NULL) {
690 Status = EFI_OUT_OF_RESOURCES;
691 goto ON_EXIT;
692 }
693
694 //
695 // Fill Certificate Database parameters.
696 //
697 CACert = (EFI_SIGNATURE_LIST*) Data;
698 CACert->SignatureListSize = (UINT32) SigDataSize;
699 CACert->SignatureHeaderSize = 0;
700 CACert->SignatureSize = (UINT32) (sizeof(EFI_SIGNATURE_DATA) - 1 + X509DataSize);
701 CopyGuid (&CACert->SignatureType, &gEfiCertX509Guid);
702
703 CACertData = (EFI_SIGNATURE_DATA*) ((UINT8* ) CACert + sizeof (EFI_SIGNATURE_LIST));
704 CopyGuid (&CACertData->SignatureOwner, Private->CertGuid);
705 CopyMem ((UINT8* ) (CACertData->SignatureData), X509Data, X509DataSize);
706
707 //
708 // Check if the signature database entry already exists. If it does, use the
709 // EFI_VARIABLE_APPEND_WRITE attribute to append the new signature data to
710 // the original variable, plus preserve the original variable attributes.
711 //
712 Status = gRT->GetVariable(
713 VariableName,
714 &gEfiTlsCaCertificateGuid,
715 NULL,
716 &DataSize,
717 NULL
718 );
719 if (Status == EFI_BUFFER_TOO_SMALL) {
720 //
721 // Per spec, we have to fetch the variable's contents, even though we're
722 // only interested in the variable's attributes.
723 //
724 CurrentData = AllocatePool (DataSize);
725 if (CurrentData == NULL) {
726 Status = EFI_OUT_OF_RESOURCES;
727 goto ON_EXIT;
728 }
729 Status = gRT->GetVariable(
730 VariableName,
731 &gEfiTlsCaCertificateGuid,
732 &Attr,
733 &DataSize,
734 CurrentData
735 );
736 if (EFI_ERROR (Status)) {
737 goto ON_EXIT;
738 }
739 Attr |= EFI_VARIABLE_APPEND_WRITE;
740 } else if (Status == EFI_NOT_FOUND) {
741 Attr = TLS_AUTH_CONFIG_VAR_BASE_ATTR;
742 } else {
743 goto ON_EXIT;
744 }
745
746 Status = gRT->SetVariable(
747 VariableName,
748 &gEfiTlsCaCertificateGuid,
749 Attr,
750 SigDataSize,
751 Data
752 );
753 if (EFI_ERROR (Status)) {
754 goto ON_EXIT;
755 }
756
757 ON_EXIT:
758 CleanFileContext (Private);
759
760 if (Private->CertGuid != NULL) {
761 FreePool (Private->CertGuid);
762 Private->CertGuid = NULL;
763 }
764
765 if (Data != NULL) {
766 FreePool (Data);
767 }
768
769 if (CurrentData != NULL) {
770 FreePool (CurrentData);
771 }
772
773 if (X509Data != NULL) {
774 FreePool (X509Data);
775 }
776
777 return Status;
778 }
779
780 /**
781 Enroll Cert into TlsCaCertificate. The GUID will be Private->CertGuid.
782
783 @param[in] PrivateData The module's private data.
784 @param[in] VariableName Variable name of signature database.
785
786 @retval EFI_SUCCESS New Cert enrolled successfully.
787 @retval EFI_INVALID_PARAMETER The parameter is invalid.
788 @retval EFI_UNSUPPORTED The Cert file is unsupported type.
789 @retval others Fail to enroll Cert data.
790
791 **/
792 EFI_STATUS
793 EnrollCertDatabase (
794 IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
795 IN CHAR16 *VariableName
796 )
797 {
798 UINT16* FilePostFix;
799 UINTN NameLength;
800
801 if ((Private->FileContext->FileName == NULL) || (Private->FileContext->FHandle == NULL) || (Private->CertGuid == NULL)) {
802 return EFI_INVALID_PARAMETER;
803 }
804
805 //
806 // Parse the file's postfix.
807 //
808 NameLength = StrLen (Private->FileContext->FileName);
809 if (NameLength <= 4) {
810 return EFI_INVALID_PARAMETER;
811 }
812 FilePostFix = Private->FileContext->FileName + NameLength - 4;
813
814 if (IsDerPemEncodeCertificate (FilePostFix)) {
815 //
816 // Supports DER-encoded X509 certificate.
817 //
818 return EnrollX509toVariable (Private, VariableName);
819 }
820
821 return EFI_UNSUPPORTED;
822 }
823
824 /**
825 Refresh the global UpdateData structure.
826
827 **/
828 VOID
829 RefreshUpdateData (
830 VOID
831 )
832 {
833 //
834 // Free current updated date
835 //
836 if (mStartOpCodeHandle != NULL) {
837 HiiFreeOpCodeHandle (mStartOpCodeHandle);
838 }
839
840 //
841 // Create new OpCode Handle
842 //
843 mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
844
845 //
846 // Create Hii Extend Label OpCode as the start opcode
847 //
848 mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
849 mStartOpCodeHandle,
850 &gEfiIfrTianoGuid,
851 NULL,
852 sizeof (EFI_IFR_GUID_LABEL)
853 );
854 mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
855 }
856
857 /**
858 Clean up the dynamic opcode at label and form specified by both LabelId.
859
860 @param[in] LabelId It is both the Form ID and Label ID for opcode deletion.
861 @param[in] PrivateData Module private data.
862
863 **/
864 VOID
865 CleanUpPage (
866 IN UINT16 LabelId,
867 IN TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData
868 )
869 {
870 RefreshUpdateData ();
871
872 //
873 // Remove all op-codes from dynamic page
874 //
875 mStartLabel->Number = LabelId;
876 HiiUpdateForm (
877 PrivateData->RegisteredHandle,
878 &gTlsAuthConfigGuid,
879 LabelId,
880 mStartOpCodeHandle, // Label LabelId
881 mEndOpCodeHandle // LABEL_END
882 );
883 }
884
885 /**
886 Update the form base on the selected file.
887
888 @param FilePath Point to the file path.
889 @param FormId The form need to display.
890
891 @retval TRUE Exit caller function.
892 @retval FALSE Not exit caller function.
893
894 **/
895 BOOLEAN
896 UpdatePage(
897 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
898 IN EFI_FORM_ID FormId
899 )
900 {
901 CHAR16 *FileName;
902 EFI_STRING_ID StringToken;
903
904 FileName = NULL;
905
906 if (FilePath != NULL) {
907 FileName = ExtractFileNameFromDevicePath(FilePath);
908 }
909 if (FileName == NULL) {
910 //
911 // FileName = NULL has two case:
912 // 1. FilePath == NULL, not select file.
913 // 2. FilePath != NULL, but ExtractFileNameFromDevicePath return NULL not enough memory resource.
914 // In these two case, no need to update the form, and exit the caller function.
915 //
916 return TRUE;
917 }
918 StringToken = HiiSetString (mTlsAuthPrivateData->RegisteredHandle, 0, FileName, NULL);
919
920 mTlsAuthPrivateData->FileContext->FileName = FileName;
921
922 EfiOpenFileByDevicePath (
923 &FilePath,
924 &mTlsAuthPrivateData->FileContext->FHandle,
925 EFI_FILE_MODE_READ,
926 0
927 );
928 //
929 // Create Subtitle op-code for the display string of the option.
930 //
931 RefreshUpdateData ();
932 mStartLabel->Number = FormId;
933
934 HiiCreateSubTitleOpCode (
935 mStartOpCodeHandle,
936 StringToken,
937 0,
938 0,
939 0
940 );
941
942 HiiUpdateForm (
943 mTlsAuthPrivateData->RegisteredHandle,
944 &gTlsAuthConfigGuid,
945 FormId,
946 mStartOpCodeHandle, /// Label FormId
947 mEndOpCodeHandle /// LABEL_END
948 );
949
950 return TRUE;
951 }
952
953 /**
954 Update the form base on the input file path info.
955
956 @param FilePath Point to the file path.
957
958 @retval TRUE Exit caller function.
959 @retval FALSE Not exit caller function.
960 **/
961 BOOLEAN
962 EFIAPI
963 UpdateCAFromFile (
964 IN EFI_DEVICE_PATH_PROTOCOL *FilePath
965 )
966 {
967 return UpdatePage(FilePath, TLS_AUTH_CONFIG_FORMID4_FORM);
968 }
969
970 /**
971 Unload the configuration form, this includes: delete all the configuration
972 entries, uninstall the form callback protocol, and free the resources used.
973
974 @param[in] Private Pointer to the driver private data.
975
976 @retval EFI_SUCCESS The configuration form is unloaded.
977 @retval Others Failed to unload the form.
978
979 **/
980 EFI_STATUS
981 TlsAuthConfigFormUnload (
982 IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
983 )
984 {
985 if (Private->DriverHandle != NULL) {
986 //
987 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
988 //
989 gBS->UninstallMultipleProtocolInterfaces (
990 Private->DriverHandle,
991 &gEfiDevicePathProtocolGuid,
992 &mTlsAuthConfigHiiVendorDevicePath,
993 &gEfiHiiConfigAccessProtocolGuid,
994 &Private->ConfigAccess,
995 NULL
996 );
997 Private->DriverHandle = NULL;
998 }
999
1000 if (Private->RegisteredHandle != NULL) {
1001 //
1002 // Remove HII package list
1003 //
1004 HiiRemovePackages (Private->RegisteredHandle);
1005 Private->RegisteredHandle = NULL;
1006 }
1007
1008 if (Private->CertGuid != NULL) {
1009 FreePool (Private->CertGuid);
1010 }
1011
1012 if (Private->FileContext != NULL) {
1013 FreePool (Private->FileContext);
1014 }
1015
1016 FreePool (Private);
1017
1018 if (mStartOpCodeHandle != NULL) {
1019 HiiFreeOpCodeHandle (mStartOpCodeHandle);
1020 }
1021
1022 if (mEndOpCodeHandle != NULL) {
1023 HiiFreeOpCodeHandle (mEndOpCodeHandle);
1024 }
1025
1026 return EFI_SUCCESS;
1027 }
1028
1029
1030 /**
1031 Initialize the configuration form.
1032
1033 @param[in] Private Pointer to the driver private data.
1034
1035 @retval EFI_SUCCESS The configuration form is initialized.
1036 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1037
1038 **/
1039 EFI_STATUS
1040 TlsAuthConfigFormInit (
1041 IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
1042 )
1043 {
1044 EFI_STATUS Status;
1045
1046 Private->Signature = TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE;
1047
1048 Private->ConfigAccess.ExtractConfig = TlsAuthConfigAccessExtractConfig;
1049 Private->ConfigAccess.RouteConfig = TlsAuthConfigAccessRouteConfig;
1050 Private->ConfigAccess.Callback = TlsAuthConfigAccessCallback;
1051
1052 //
1053 // Install Device Path Protocol and Config Access protocol to driver handle.
1054 //
1055 Status = gBS->InstallMultipleProtocolInterfaces (
1056 &Private->DriverHandle,
1057 &gEfiDevicePathProtocolGuid,
1058 &mTlsAuthConfigHiiVendorDevicePath,
1059 &gEfiHiiConfigAccessProtocolGuid,
1060 &Private->ConfigAccess,
1061 NULL
1062 );
1063 if (EFI_ERROR (Status)) {
1064 return Status;
1065 }
1066
1067 //
1068 // Publish our HII data.
1069 //
1070 Private->RegisteredHandle = HiiAddPackages (
1071 &gTlsAuthConfigGuid,
1072 Private->DriverHandle,
1073 TlsAuthConfigDxeStrings,
1074 TlsAuthConfigVfrBin,
1075 NULL
1076 );
1077 if (Private->RegisteredHandle == NULL) {
1078 Status = EFI_OUT_OF_RESOURCES;
1079 goto Error;
1080 }
1081
1082 Private->FileContext = AllocateZeroPool (sizeof (TLS_AUTH_CONFIG_FILE_CONTEXT));
1083 if (Private->FileContext == NULL) {
1084 Status = EFI_OUT_OF_RESOURCES;
1085 goto Error;
1086 }
1087
1088 //
1089 // Init OpCode Handle and Allocate space for creation of Buffer
1090 //
1091 mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
1092 if (mStartOpCodeHandle == NULL) {
1093 Status = EFI_OUT_OF_RESOURCES;
1094 goto Error;
1095 }
1096
1097 mEndOpCodeHandle = HiiAllocateOpCodeHandle ();
1098 if (mEndOpCodeHandle == NULL) {
1099 Status = EFI_OUT_OF_RESOURCES;
1100 goto Error;
1101 }
1102
1103 //
1104 // Create Hii Extend Label OpCode as the start opcode
1105 //
1106 mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
1107 mStartOpCodeHandle,
1108 &gEfiIfrTianoGuid,
1109 NULL,
1110 sizeof (EFI_IFR_GUID_LABEL)
1111 );
1112 mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1113
1114 //
1115 // Create Hii Extend Label OpCode as the end opcode
1116 //
1117 mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
1118 mEndOpCodeHandle,
1119 &gEfiIfrTianoGuid,
1120 NULL,
1121 sizeof (EFI_IFR_GUID_LABEL)
1122 );
1123 mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1124 mEndLabel->Number = LABEL_END;
1125
1126 return EFI_SUCCESS;
1127
1128 Error:
1129 TlsAuthConfigFormUnload (Private);
1130 return Status;
1131 }
1132
1133 /**
1134
1135 This function allows the caller to request the current
1136 configuration for one or more named elements. The resulting
1137 string is in <ConfigAltResp> format. Any and all alternative
1138 configuration strings shall also be appended to the end of the
1139 current configuration string. If they are, they must appear
1140 after the current configuration. They must contain the same
1141 routing (GUID, NAME, PATH) as the current configuration string.
1142 They must have an additional description indicating the type of
1143 alternative configuration the string represents,
1144 "ALTCFG=<StringToken>". That <StringToken> (when
1145 converted from Hex UNICODE to binary) is a reference to a
1146 string in the associated string pack.
1147
1148 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1149
1150 @param Request A null-terminated Unicode string in
1151 <ConfigRequest> format. Note that this
1152 includes the routing information as well as
1153 the configurable name / value pairs. It is
1154 invalid for this string to be in
1155 <MultiConfigRequest> format.
1156 If a NULL is passed in for the Request field,
1157 all of the settings being abstracted by this function
1158 will be returned in the Results field. In addition,
1159 if a ConfigHdr is passed in with no request elements,
1160 all of the settings being abstracted for that particular
1161 ConfigHdr reference will be returned in the Results Field.
1162
1163 @param Progress On return, points to a character in the
1164 Request string. Points to the string's null
1165 terminator if request was successful. Points
1166 to the most recent "&" before the first
1167 failing name / value pair (or the beginning
1168 of the string if the failure is in the first
1169 name / value pair) if the request was not
1170 successful.
1171
1172 @param Results A null-terminated Unicode string in
1173 <MultiConfigAltResp> format which has all values
1174 filled in for the names in the Request string.
1175 String to be allocated by the called function.
1176
1177 @retval EFI_SUCCESS The Results string is filled with the
1178 values corresponding to all requested
1179 names.
1180
1181 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
1182 parts of the results that must be
1183 stored awaiting possible future
1184 protocols.
1185
1186 @retval EFI_NOT_FOUND Routing data doesn't match any
1187 known driver. Progress set to the
1188 first character in the routing header.
1189 Note: There is no requirement that the
1190 driver validate the routing data. It
1191 must skip the <ConfigHdr> in order to
1192 process the names.
1193
1194 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
1195 to most recent "&" before the
1196 error or the beginning of the
1197 string.
1198
1199 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
1200 to the & before the name in
1201 question.
1202
1203 **/
1204 EFI_STATUS
1205 EFIAPI
1206 TlsAuthConfigAccessExtractConfig (
1207 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1208 IN CONST EFI_STRING Request,
1209 OUT EFI_STRING *Progress,
1210 OUT EFI_STRING *Results
1211 )
1212 {
1213 EFI_STATUS Status;
1214 UINTN BufferSize;
1215 UINTN Size;
1216 EFI_STRING ConfigRequest;
1217 EFI_STRING ConfigRequestHdr;
1218 TLS_AUTH_CONFIG_PRIVATE_DATA *Private;
1219 BOOLEAN AllocatedRequest;
1220
1221 if (Progress == NULL || Results == NULL) {
1222 return EFI_INVALID_PARAMETER;
1223 }
1224
1225 AllocatedRequest = FALSE;
1226 ConfigRequestHdr = NULL;
1227 ConfigRequest = NULL;
1228 Size = 0;
1229
1230 Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
1231
1232 BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
1233 ZeroMem (&Private->TlsAuthConfigNvData, BufferSize);
1234
1235 *Progress = Request;
1236
1237 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) {
1238 return EFI_NOT_FOUND;
1239 }
1240
1241 ConfigRequest = Request;
1242 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
1243 //
1244 // Request is set to NULL or OFFSET is NULL, construct full request string.
1245 //
1246 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1247 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
1248 //
1249 ConfigRequestHdr = HiiConstructConfigHdr (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, Private->DriverHandle);
1250 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
1251 ConfigRequest = AllocateZeroPool (Size);
1252 ASSERT (ConfigRequest != NULL);
1253 AllocatedRequest = TRUE;
1254 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
1255 FreePool (ConfigRequestHdr);
1256 ConfigRequestHdr = NULL;
1257 }
1258
1259 Status = gHiiConfigRouting->BlockToConfig (
1260 gHiiConfigRouting,
1261 ConfigRequest,
1262 (UINT8 *) &Private->TlsAuthConfigNvData,
1263 BufferSize,
1264 Results,
1265 Progress
1266 );
1267
1268 //
1269 // Free the allocated config request string.
1270 //
1271 if (AllocatedRequest) {
1272 FreePool (ConfigRequest);
1273 }
1274
1275 //
1276 // Set Progress string to the original request string.
1277 //
1278 if (Request == NULL) {
1279 *Progress = NULL;
1280 } else if (StrStr (Request, L"OFFSET") == NULL) {
1281 *Progress = Request + StrLen (Request);
1282 }
1283
1284 return Status;
1285 }
1286
1287 /**
1288
1289 This function applies changes in a driver's configuration.
1290 Input is a Configuration, which has the routing data for this
1291 driver followed by name / value configuration pairs. The driver
1292 must apply those pairs to its configurable storage. If the
1293 driver's configuration is stored in a linear block of data
1294 and the driver's name / value pairs are in <BlockConfig>
1295 format, it may use the ConfigToBlock helper function (above) to
1296 simplify the job.
1297
1298 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1299
1300 @param Configuration A null-terminated Unicode string in
1301 <ConfigString> format.
1302
1303 @param Progress A pointer to a string filled in with the
1304 offset of the most recent '&' before the
1305 first failing name / value pair (or the
1306 beginning of the string if the failure
1307 is in the first name / value pair) or
1308 the terminating NULL if all was
1309 successful.
1310
1311 @retval EFI_SUCCESS The results have been distributed or are
1312 awaiting distribution.
1313
1314 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
1315 parts of the results that must be
1316 stored awaiting possible future
1317 protocols.
1318
1319 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
1320 Results parameter would result
1321 in this type of error.
1322
1323 @retval EFI_NOT_FOUND Target for the specified routing data
1324 was not found
1325
1326 **/
1327 EFI_STATUS
1328 EFIAPI
1329 TlsAuthConfigAccessRouteConfig (
1330 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1331 IN CONST EFI_STRING Configuration,
1332 OUT EFI_STRING *Progress
1333 )
1334 {
1335 EFI_STATUS Status;
1336 UINTN BufferSize;
1337 TLS_AUTH_CONFIG_PRIVATE_DATA *Private;
1338
1339 if (Progress == NULL) {
1340 return EFI_INVALID_PARAMETER;
1341 }
1342 *Progress = Configuration;
1343
1344 if (Configuration == NULL) {
1345 return EFI_INVALID_PARAMETER;
1346 }
1347
1348 //
1349 // Check routing data in <ConfigHdr>.
1350 // Note: there is no name for Name/Value storage, only GUID will be checked
1351 //
1352 if (!HiiIsConfigHdrMatch (Configuration, &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) {
1353 return EFI_NOT_FOUND;
1354 }
1355
1356 Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
1357
1358 BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
1359 ZeroMem (&Private->TlsAuthConfigNvData, BufferSize);
1360
1361 Status = gHiiConfigRouting->ConfigToBlock (
1362 gHiiConfigRouting,
1363 Configuration,
1364 (UINT8 *) &Private->TlsAuthConfigNvData,
1365 &BufferSize,
1366 Progress
1367 );
1368 if (EFI_ERROR (Status)) {
1369 return Status;
1370 }
1371
1372 return Status;
1373 }
1374
1375 /**
1376
1377 This function is called to provide results data to the driver.
1378 This data consists of a unique key that is used to identify
1379 which data is either being passed back or being asked for.
1380
1381 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1382 @param Action Specifies the type of action taken by the browser.
1383 @param QuestionId A unique value which is sent to the original
1384 exporting driver so that it can identify the type
1385 of data to expect. The format of the data tends to
1386 vary based on the opcode that generated the callback.
1387 @param Type The type of value for the question.
1388 @param Value A pointer to the data being sent to the original
1389 exporting driver.
1390 @param ActionRequest On return, points to the action requested by the
1391 callback function.
1392
1393 @retval EFI_SUCCESS The callback successfully handled the action.
1394 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1395 variable and its data.
1396 @retval EFI_DEVICE_ERROR The variable could not be saved.
1397 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1398 callback.
1399 **/
1400 EFI_STATUS
1401 EFIAPI
1402 TlsAuthConfigAccessCallback (
1403 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1404 IN EFI_BROWSER_ACTION Action,
1405 IN EFI_QUESTION_ID QuestionId,
1406 IN UINT8 Type,
1407 IN OUT EFI_IFR_TYPE_VALUE *Value,
1408 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
1409 )
1410 {
1411 EFI_INPUT_KEY Key;
1412 EFI_STATUS Status;
1413 RETURN_STATUS RStatus;
1414 TLS_AUTH_CONFIG_PRIVATE_DATA *Private;
1415 UINTN BufferSize;
1416 TLS_AUTH_CONFIG_IFR_NVDATA *IfrNvData;
1417 UINT16 LabelId;
1418 EFI_DEVICE_PATH_PROTOCOL *File;
1419
1420 Status = EFI_SUCCESS;
1421 File = NULL;
1422
1423 if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
1424 return EFI_INVALID_PARAMETER;
1425 }
1426
1427 Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
1428
1429 mTlsAuthPrivateData = Private;
1430
1431 //
1432 // Retrieve uncommitted data from Browser
1433 //
1434 BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
1435 IfrNvData = AllocateZeroPool (BufferSize);
1436 if (IfrNvData == NULL) {
1437 return EFI_OUT_OF_RESOURCES;
1438 }
1439
1440 HiiGetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, BufferSize, (UINT8 *) IfrNvData);
1441
1442 if ((Action != EFI_BROWSER_ACTION_CHANGED) &&
1443 (Action != EFI_BROWSER_ACTION_CHANGING) &&
1444 (Action != EFI_BROWSER_ACTION_FORM_CLOSE)) {
1445 Status = EFI_UNSUPPORTED;
1446 goto EXIT;
1447 }
1448
1449 if (Action == EFI_BROWSER_ACTION_CHANGING) {
1450 switch (QuestionId) {
1451 case KEY_TLS_AUTH_CONFIG_CLIENT_CERT:
1452 case KEY_TLS_AUTH_CONFIG_SERVER_CA:
1453 //
1454 // Clear Cert GUID.
1455 //
1456 ZeroMem (IfrNvData->CertGuid, sizeof (IfrNvData->CertGuid));
1457 if (Private->CertGuid == NULL) {
1458 Private->CertGuid = (EFI_GUID *) AllocateZeroPool (sizeof (EFI_GUID));
1459 if (Private->CertGuid == NULL) {
1460 return EFI_OUT_OF_RESOURCES;
1461 }
1462 }
1463 if (QuestionId == KEY_TLS_AUTH_CONFIG_CLIENT_CERT) {
1464 LabelId = TLS_AUTH_CONFIG_FORMID3_FORM;
1465 } else {
1466 LabelId = TLS_AUTH_CONFIG_FORMID4_FORM;
1467 }
1468
1469 //
1470 // Refresh selected file.
1471 //
1472 CleanUpPage (LabelId, Private);
1473 break;
1474 case KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE:
1475 //
1476 // If the file is already opened, clean the file related resource first.
1477 //
1478 CleanFileContext (Private);
1479
1480 ChooseFile( NULL, NULL, UpdateCAFromFile, &File);
1481 break;
1482
1483 case KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT:
1484 Status = EnrollCertDatabase (Private, EFI_TLS_CA_CERTIFICATE_VARIABLE);
1485 if (EFI_ERROR (Status)) {
1486 CleanFileContext (Private);
1487
1488 CreatePopUp (
1489 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1490 &Key,
1491 L"ERROR: Enroll Cert Failure!",
1492 NULL
1493 );
1494 }
1495 break;
1496
1497 case KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT:
1498 CleanFileContext (Private);
1499
1500 if (Private->CertGuid!= NULL) {
1501 FreePool (Private->CertGuid);
1502 Private->CertGuid = NULL;
1503 }
1504 break;
1505
1506 case KEY_TLS_AUTH_CONFIG_DELETE_CERT:
1507 UpdateDeletePage (
1508 Private,
1509 EFI_TLS_CA_CERTIFICATE_VARIABLE,
1510 &gEfiTlsCaCertificateGuid,
1511 LABEL_CA_DELETE,
1512 TLS_AUTH_CONFIG_FORMID5_FORM,
1513 OPTION_DEL_CA_ESTION_ID
1514 );
1515 break;
1516
1517 default:
1518 if ((QuestionId >= OPTION_DEL_CA_ESTION_ID) &&
1519 (QuestionId < (OPTION_DEL_CA_ESTION_ID + OPTION_CONFIG_RANGE))) {
1520 DeleteCert (
1521 Private,
1522 EFI_TLS_CA_CERTIFICATE_VARIABLE,
1523 &gEfiTlsCaCertificateGuid,
1524 LABEL_CA_DELETE,
1525 TLS_AUTH_CONFIG_FORMID5_FORM,
1526 OPTION_DEL_CA_ESTION_ID,
1527 QuestionId - OPTION_DEL_CA_ESTION_ID
1528 );
1529 }
1530 break;
1531 }
1532 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
1533 switch (QuestionId) {
1534 case KEY_TLS_AUTH_CONFIG_CERT_GUID:
1535 ASSERT (Private->CertGuid != NULL);
1536 RStatus = StrToGuid (
1537 IfrNvData->CertGuid,
1538 Private->CertGuid
1539 );
1540 if (RETURN_ERROR (RStatus) || (IfrNvData->CertGuid[GUID_STRING_LENGTH] != L'\0')) {
1541 Status = EFI_INVALID_PARAMETER;
1542 break;
1543 }
1544
1545 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
1546 break;
1547 default:
1548 break;
1549 }
1550 } else if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) {
1551 CleanFileContext (Private);
1552 }
1553
1554 EXIT:
1555
1556 if (!EFI_ERROR (Status)) {
1557 BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
1558 HiiSetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, BufferSize, (UINT8*) IfrNvData, NULL);
1559 }
1560
1561 FreePool (IfrNvData);
1562
1563 if (File != NULL){
1564 FreePool(File);
1565 File = NULL;
1566 }
1567
1568 return EFI_SUCCESS;
1569
1570 }
1571