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