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