2 The Miscellaneous Routines for TlsAuthConfigDxe driver.
4 Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "TlsAuthConfigImpl.h"
12 VOID
*mStartOpCodeHandle
= NULL
;
13 VOID
*mEndOpCodeHandle
= NULL
;
14 EFI_IFR_GUID_LABEL
*mStartLabel
= NULL
;
15 EFI_IFR_GUID_LABEL
*mEndLabel
= NULL
;
18 CHAR16 mTlsAuthConfigStorageName
[] = L
"TLS_AUTH_CONFIG_IFR_NVDATA";
20 TLS_AUTH_CONFIG_PRIVATE_DATA
*mTlsAuthPrivateData
= NULL
;
22 HII_VENDOR_DEVICE_PATH mTlsAuthConfigHiiVendorDevicePath
= {
28 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
29 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
36 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
38 (UINT8
) (END_DEVICE_PATH_LENGTH
),
39 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
45 // Possible DER-encoded certificate file suffixes, end with NULL pointer.
47 CHAR16
* mDerPemEncodedSuffix
[] = {
56 This code checks if the FileSuffix is one of the possible DER/PEM-encoded certificate suffix.
58 @param[in] FileSuffix The suffix of the input certificate file
60 @retval TRUE It's a DER/PEM-encoded certificate.
61 @retval FALSE It's NOT a DER/PEM-encoded certificate.
65 IsDerPemEncodeCertificate (
66 IN CONST CHAR16
*FileSuffix
70 for (Index
= 0; mDerPemEncodedSuffix
[Index
] != NULL
; Index
++) {
71 if (StrCmp (FileSuffix
, mDerPemEncodedSuffix
[Index
]) == 0) {
79 Worker function that prints an EFI_GUID into specified Buffer.
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.
85 @retval Number of characters printed.
95 return UnicodeSPrint (
104 List all cert in specified database by GUID in the page
105 for user to select and delete as needed.
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.
114 @retval EFI_SUCCESS Success to update the signature list page
115 @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
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
132 VOID
*StartOpCodeHandle
;
133 VOID
*EndOpCodeHandle
;
134 EFI_IFR_GUID_LABEL
*StartLabel
;
135 EFI_IFR_GUID_LABEL
*EndLabel
;
138 EFI_SIGNATURE_LIST
*CertList
;
139 EFI_SIGNATURE_DATA
*Cert
;
142 EFI_STRING_ID GuidID
;
149 StartOpCodeHandle
= NULL
;
150 EndOpCodeHandle
= NULL
;
153 // Initialize the container for dynamic opcodes.
155 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
156 if (StartOpCodeHandle
== NULL
) {
157 Status
= EFI_OUT_OF_RESOURCES
;
161 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
162 if (EndOpCodeHandle
== NULL
) {
163 Status
= EFI_OUT_OF_RESOURCES
;
168 // Create Hii Extend Label OpCode.
170 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
174 sizeof (EFI_IFR_GUID_LABEL
)
176 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
177 StartLabel
->Number
= LabelNumber
;
179 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
183 sizeof (EFI_IFR_GUID_LABEL
)
185 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
186 EndLabel
->Number
= LABEL_END
;
192 Status
= gRT
->GetVariable (VariableName
, VendorGuid
, NULL
, &DataSize
, Data
);
193 if (EFI_ERROR (Status
) && Status
!= EFI_BUFFER_TOO_SMALL
) {
197 Data
= (UINT8
*) AllocateZeroPool (DataSize
);
199 Status
= EFI_OUT_OF_RESOURCES
;
203 Status
= gRT
->GetVariable (VariableName
, VendorGuid
, NULL
, &DataSize
, Data
);
204 if (EFI_ERROR (Status
)) {
208 GuidStr
= AllocateZeroPool (100);
209 if (GuidStr
== NULL
) {
210 Status
= EFI_OUT_OF_RESOURCES
;
215 // Enumerate all data.
217 ItemDataSize
= (UINT32
) DataSize
;
218 CertList
= (EFI_SIGNATURE_LIST
*) Data
;
221 while ((ItemDataSize
> 0) && (ItemDataSize
>= CertList
->SignatureListSize
)) {
223 if (CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Guid
)) {
224 Help
= STRING_TOKEN (STR_CERT_TYPE_PCKS_GUID
);
227 // The signature type is not supported in current implementation.
229 ItemDataSize
-= CertList
->SignatureListSize
;
230 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
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
);
241 // Display GUID and help
243 GuidToString (&Cert
->SignatureOwner
, GuidStr
, 100);
244 GuidID
= HiiSetString (Private
->RegisteredHandle
, 0, GuidStr
, NULL
);
245 HiiCreateCheckBoxOpCode (
247 (EFI_QUESTION_ID
) (QuestionIdBase
+ GuidIndex
++),
252 EFI_IFR_FLAG_CALLBACK
,
258 ItemDataSize
-= CertList
->SignatureListSize
;
259 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
264 Private
->RegisteredHandle
,
271 if (StartOpCodeHandle
!= NULL
) {
272 HiiFreeOpCodeHandle (StartOpCodeHandle
);
275 if (EndOpCodeHandle
!= NULL
) {
276 HiiFreeOpCodeHandle (EndOpCodeHandle
);
283 if (GuidStr
!= NULL
) {
291 Delete one entry from cert database.
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.
301 @retval EFI_SUCCESS Delete siganture successfully.
302 @retval EFI_NOT_FOUND Can't find the signature item,
303 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
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
,
322 EFI_SIGNATURE_LIST
*CertList
;
323 EFI_SIGNATURE_LIST
*NewCertList
;
324 EFI_SIGNATURE_DATA
*Cert
;
338 // Get original signature list data.
341 Status
= gRT
->GetVariable (VariableName
, VendorGuid
, NULL
, &DataSize
, NULL
);
342 if (EFI_ERROR (Status
) && Status
!= EFI_BUFFER_TOO_SMALL
) {
346 OldData
= (UINT8
*) AllocateZeroPool (DataSize
);
347 if (OldData
== NULL
) {
348 Status
= EFI_OUT_OF_RESOURCES
;
352 Status
= gRT
->GetVariable (VariableName
, VendorGuid
, &Attr
, &DataSize
, OldData
);
353 if (EFI_ERROR(Status
)) {
358 // Allocate space for new variable.
360 Data
= (UINT8
*) AllocateZeroPool (DataSize
);
362 Status
= EFI_OUT_OF_RESOURCES
;
367 // Enumerate all data and erasing the target item.
370 ItemDataSize
= (UINT32
) DataSize
;
371 CertList
= (EFI_SIGNATURE_LIST
*) OldData
;
374 while ((ItemDataSize
> 0) && (ItemDataSize
>= CertList
->SignatureListSize
)) {
375 if (CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Guid
)) {
377 // Copy EFI_SIGNATURE_LIST header then calculate the signature count in this list.
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
) {
389 NewCertList
->SignatureListSize
-= CertList
->SignatureSize
;
393 // This item doesn't match. Copy it to the Data buffer.
395 CopyMem (Data
+ Offset
, (UINT8
*)(Cert
), CertList
->SignatureSize
);
396 Offset
+= CertList
->SignatureSize
;
399 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) Cert
+ CertList
->SignatureSize
);
403 // This List doesn't match. Just copy it to the Data buffer.
405 CopyMem (Data
+ Offset
, (UINT8
*)(CertList
), CertList
->SignatureListSize
);
406 Offset
+= CertList
->SignatureListSize
;
409 ItemDataSize
-= CertList
->SignatureListSize
;
410 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
415 // Doesn't find the signature Item!
417 Status
= EFI_NOT_FOUND
;
422 // Delete the EFI_SIGNATURE_LIST header if there is no signature in the list.
424 ItemDataSize
= Offset
;
425 CertList
= (EFI_SIGNATURE_LIST
*) Data
;
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
;
435 ItemDataSize
-= CertList
->SignatureListSize
;
436 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
441 Status
= gRT
->SetVariable(
448 if (EFI_ERROR (Status
)) {
449 DEBUG ((DEBUG_ERROR
, "Failed to set variable, Status = %r\n", Status
));
458 if (OldData
!= NULL
) {
462 return UpdateDeletePage (
474 Clean the file related resource.
476 @param[in] Private Module's private data.
481 IN TLS_AUTH_CONFIG_PRIVATE_DATA
*Private
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
;
495 Read file content into BufferPtr, the size of the allocate buffer
496 is *FileSize plus AddtionAllocateSize.
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.
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.
512 IN EFI_FILE_HANDLE FileHandle
,
513 IN OUT VOID
**BufferPtr
,
515 IN UINTN AddtionAllocateSize
520 UINT64 SourceFileSize
;
524 if ((FileHandle
== NULL
) || (FileSize
== NULL
)) {
525 return EFI_INVALID_PARAMETER
;
533 Status
= FileHandle
->SetPosition (FileHandle
, (UINT64
) -1);
534 if (EFI_ERROR (Status
)) {
538 Status
= FileHandle
->GetPosition (FileHandle
, &SourceFileSize
);
539 if (EFI_ERROR (Status
)) {
543 Status
= FileHandle
->SetPosition (FileHandle
, 0);
544 if (EFI_ERROR (Status
)) {
548 BufferSize
= (UINTN
) SourceFileSize
+ AddtionAllocateSize
;
549 Buffer
= AllocateZeroPool(BufferSize
);
550 if (Buffer
== NULL
) {
551 return EFI_OUT_OF_RESOURCES
;
554 BufferSize
= (UINTN
) SourceFileSize
;
555 *FileSize
= BufferSize
;
557 Status
= FileHandle
->Read (FileHandle
, &BufferSize
, Buffer
);
558 if (EFI_ERROR (Status
) || BufferSize
!= *FileSize
) {
561 Status
= EFI_BAD_BUFFER_SIZE
;
572 This function converts an input device structure to a Unicode string.
574 @param[in] DevPath A pointer to the device path structure.
576 @return A new allocated Unicode string that represents the device path.
582 IN EFI_DEVICE_PATH_PROTOCOL
*DevPath
585 return ConvertDevicePathToText (
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.
598 @param DevicePath Device path.
600 @retval NULL Not enough memory resourece for AllocateCopyPool.
601 @retval Other A new allocated string that represents the file name.
605 ExtractFileNameFromDevicePath (
606 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
615 ASSERT(DevicePath
!= NULL
);
617 String
= DevicePathToStr(DevicePath
);
618 MatchString
= String
;
622 while(MatchString
!= NULL
){
623 LastMatch
= MatchString
+ 1;
624 MatchString
= StrStr(LastMatch
,L
"\\");
627 Length
= StrLen(LastMatch
);
628 FileName
= AllocateCopyPool ((Length
+ 1) * sizeof(CHAR16
), LastMatch
);
629 if (FileName
!= NULL
) {
630 *(FileName
+ Length
) = 0;
639 Enroll a new X509 certificate into Variable.
641 @param[in] PrivateData The module's private data.
642 @param[in] VariableName Variable name of CA database.
644 @retval EFI_SUCCESS New X509 is enrolled successfully.
645 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
649 EnrollX509toVariable (
650 IN TLS_AUTH_CONFIG_PRIVATE_DATA
*Private
,
651 IN CHAR16
*VariableName
657 EFI_SIGNATURE_LIST
*CACert
;
658 EFI_SIGNATURE_DATA
*CACertData
;
675 Status
= ReadFileContent (
676 Private
->FileContext
->FHandle
,
681 if (EFI_ERROR (Status
)) {
684 ASSERT (X509Data
!= NULL
);
686 SigDataSize
= sizeof(EFI_SIGNATURE_LIST
) + sizeof(EFI_SIGNATURE_DATA
) - 1 + X509DataSize
;
688 Data
= AllocateZeroPool (SigDataSize
);
690 Status
= EFI_OUT_OF_RESOURCES
;
695 // Fill Certificate Database parameters.
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
);
703 CACertData
= (EFI_SIGNATURE_DATA
*) ((UINT8
* ) CACert
+ sizeof (EFI_SIGNATURE_LIST
));
704 CopyGuid (&CACertData
->SignatureOwner
, Private
->CertGuid
);
705 CopyMem ((UINT8
* ) (CACertData
->SignatureData
), X509Data
, X509DataSize
);
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.
712 Status
= gRT
->GetVariable(
714 &gEfiTlsCaCertificateGuid
,
719 if (Status
== EFI_BUFFER_TOO_SMALL
) {
721 // Per spec, we have to fetch the variable's contents, even though we're
722 // only interested in the variable's attributes.
724 CurrentData
= AllocatePool (DataSize
);
725 if (CurrentData
== NULL
) {
726 Status
= EFI_OUT_OF_RESOURCES
;
729 Status
= gRT
->GetVariable(
731 &gEfiTlsCaCertificateGuid
,
736 if (EFI_ERROR (Status
)) {
739 Attr
|= EFI_VARIABLE_APPEND_WRITE
;
740 } else if (Status
== EFI_NOT_FOUND
) {
741 Attr
= TLS_AUTH_CONFIG_VAR_BASE_ATTR
;
746 Status
= gRT
->SetVariable(
748 &gEfiTlsCaCertificateGuid
,
753 if (EFI_ERROR (Status
)) {
758 CleanFileContext (Private
);
760 if (Private
->CertGuid
!= NULL
) {
761 FreePool (Private
->CertGuid
);
762 Private
->CertGuid
= NULL
;
769 if (CurrentData
!= NULL
) {
770 FreePool (CurrentData
);
773 if (X509Data
!= NULL
) {
781 Enroll Cert into TlsCaCertificate. The GUID will be Private->CertGuid.
783 @param[in] PrivateData The module's private data.
784 @param[in] VariableName Variable name of signature database.
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.
794 IN TLS_AUTH_CONFIG_PRIVATE_DATA
*Private
,
795 IN CHAR16
*VariableName
801 if ((Private
->FileContext
->FileName
== NULL
) || (Private
->FileContext
->FHandle
== NULL
) || (Private
->CertGuid
== NULL
)) {
802 return EFI_INVALID_PARAMETER
;
806 // Parse the file's postfix.
808 NameLength
= StrLen (Private
->FileContext
->FileName
);
809 if (NameLength
<= 4) {
810 return EFI_INVALID_PARAMETER
;
812 FilePostFix
= Private
->FileContext
->FileName
+ NameLength
- 4;
814 if (IsDerPemEncodeCertificate (FilePostFix
)) {
816 // Supports DER-encoded X509 certificate.
818 return EnrollX509toVariable (Private
, VariableName
);
821 return EFI_UNSUPPORTED
;
825 Refresh the global UpdateData structure.
834 // Free current updated date
836 if (mStartOpCodeHandle
!= NULL
) {
837 HiiFreeOpCodeHandle (mStartOpCodeHandle
);
841 // Create new OpCode Handle
843 mStartOpCodeHandle
= HiiAllocateOpCodeHandle ();
846 // Create Hii Extend Label OpCode as the start opcode
848 mStartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
852 sizeof (EFI_IFR_GUID_LABEL
)
854 mStartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
858 Clean up the dynamic opcode at label and form specified by both LabelId.
860 @param[in] LabelId It is both the Form ID and Label ID for opcode deletion.
861 @param[in] PrivateData Module private data.
867 IN TLS_AUTH_CONFIG_PRIVATE_DATA
*PrivateData
870 RefreshUpdateData ();
873 // Remove all op-codes from dynamic page
875 mStartLabel
->Number
= LabelId
;
877 PrivateData
->RegisteredHandle
,
880 mStartOpCodeHandle
, // Label LabelId
881 mEndOpCodeHandle
// LABEL_END
886 Update the form base on the selected file.
888 @param FilePath Point to the file path.
889 @param FormId The form need to display.
891 @retval TRUE Exit caller function.
892 @retval FALSE Not exit caller function.
897 IN EFI_DEVICE_PATH_PROTOCOL
*FilePath
,
898 IN EFI_FORM_ID FormId
902 EFI_STRING_ID StringToken
;
906 if (FilePath
!= NULL
) {
907 FileName
= ExtractFileNameFromDevicePath(FilePath
);
909 if (FileName
== NULL
) {
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.
918 StringToken
= HiiSetString (mTlsAuthPrivateData
->RegisteredHandle
, 0, FileName
, NULL
);
920 mTlsAuthPrivateData
->FileContext
->FileName
= FileName
;
922 EfiOpenFileByDevicePath (
924 &mTlsAuthPrivateData
->FileContext
->FHandle
,
929 // Create Subtitle op-code for the display string of the option.
931 RefreshUpdateData ();
932 mStartLabel
->Number
= FormId
;
934 HiiCreateSubTitleOpCode (
943 mTlsAuthPrivateData
->RegisteredHandle
,
946 mStartOpCodeHandle
, /// Label FormId
947 mEndOpCodeHandle
/// LABEL_END
954 Update the form base on the input file path info.
956 @param FilePath Point to the file path.
958 @retval TRUE Exit caller function.
959 @retval FALSE Not exit caller function.
964 IN EFI_DEVICE_PATH_PROTOCOL
*FilePath
967 return UpdatePage(FilePath
, TLS_AUTH_CONFIG_FORMID4_FORM
);
971 Unload the configuration form, this includes: delete all the configuration
972 entries, uninstall the form callback protocol, and free the resources used.
974 @param[in] Private Pointer to the driver private data.
976 @retval EFI_SUCCESS The configuration form is unloaded.
977 @retval Others Failed to unload the form.
981 TlsAuthConfigFormUnload (
982 IN TLS_AUTH_CONFIG_PRIVATE_DATA
*Private
985 if (Private
->DriverHandle
!= NULL
) {
987 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
989 gBS
->UninstallMultipleProtocolInterfaces (
990 Private
->DriverHandle
,
991 &gEfiDevicePathProtocolGuid
,
992 &mTlsAuthConfigHiiVendorDevicePath
,
993 &gEfiHiiConfigAccessProtocolGuid
,
994 &Private
->ConfigAccess
,
997 Private
->DriverHandle
= NULL
;
1000 if (Private
->RegisteredHandle
!= NULL
) {
1002 // Remove HII package list
1004 HiiRemovePackages (Private
->RegisteredHandle
);
1005 Private
->RegisteredHandle
= NULL
;
1008 if (Private
->CertGuid
!= NULL
) {
1009 FreePool (Private
->CertGuid
);
1012 if (Private
->FileContext
!= NULL
) {
1013 FreePool (Private
->FileContext
);
1018 if (mStartOpCodeHandle
!= NULL
) {
1019 HiiFreeOpCodeHandle (mStartOpCodeHandle
);
1022 if (mEndOpCodeHandle
!= NULL
) {
1023 HiiFreeOpCodeHandle (mEndOpCodeHandle
);
1031 Initialize the configuration form.
1033 @param[in] Private Pointer to the driver private data.
1035 @retval EFI_SUCCESS The configuration form is initialized.
1036 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1040 TlsAuthConfigFormInit (
1041 IN TLS_AUTH_CONFIG_PRIVATE_DATA
*Private
1046 Private
->Signature
= TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE
;
1048 Private
->ConfigAccess
.ExtractConfig
= TlsAuthConfigAccessExtractConfig
;
1049 Private
->ConfigAccess
.RouteConfig
= TlsAuthConfigAccessRouteConfig
;
1050 Private
->ConfigAccess
.Callback
= TlsAuthConfigAccessCallback
;
1053 // Install Device Path Protocol and Config Access protocol to driver handle.
1055 Status
= gBS
->InstallMultipleProtocolInterfaces (
1056 &Private
->DriverHandle
,
1057 &gEfiDevicePathProtocolGuid
,
1058 &mTlsAuthConfigHiiVendorDevicePath
,
1059 &gEfiHiiConfigAccessProtocolGuid
,
1060 &Private
->ConfigAccess
,
1063 if (EFI_ERROR (Status
)) {
1068 // Publish our HII data.
1070 Private
->RegisteredHandle
= HiiAddPackages (
1071 &gTlsAuthConfigGuid
,
1072 Private
->DriverHandle
,
1073 TlsAuthConfigDxeStrings
,
1074 TlsAuthConfigVfrBin
,
1077 if (Private
->RegisteredHandle
== NULL
) {
1078 Status
= EFI_OUT_OF_RESOURCES
;
1082 Private
->FileContext
= AllocateZeroPool (sizeof (TLS_AUTH_CONFIG_FILE_CONTEXT
));
1083 if (Private
->FileContext
== NULL
) {
1084 Status
= EFI_OUT_OF_RESOURCES
;
1089 // Init OpCode Handle and Allocate space for creation of Buffer
1091 mStartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1092 if (mStartOpCodeHandle
== NULL
) {
1093 Status
= EFI_OUT_OF_RESOURCES
;
1097 mEndOpCodeHandle
= HiiAllocateOpCodeHandle ();
1098 if (mEndOpCodeHandle
== NULL
) {
1099 Status
= EFI_OUT_OF_RESOURCES
;
1104 // Create Hii Extend Label OpCode as the start opcode
1106 mStartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
1110 sizeof (EFI_IFR_GUID_LABEL
)
1112 mStartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1115 // Create Hii Extend Label OpCode as the end opcode
1117 mEndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
1121 sizeof (EFI_IFR_GUID_LABEL
)
1123 mEndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1124 mEndLabel
->Number
= LABEL_END
;
1129 TlsAuthConfigFormUnload (Private
);
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.
1148 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
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.
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
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.
1177 @retval EFI_SUCCESS The Results string is filled with the
1178 values corresponding to all requested
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
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
1194 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
1195 to most recent "&" before the
1196 error or the beginning of the
1199 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
1200 to the & before the name in
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
1216 EFI_STRING ConfigRequest
;
1217 EFI_STRING ConfigRequestHdr
;
1218 TLS_AUTH_CONFIG_PRIVATE_DATA
*Private
;
1219 BOOLEAN AllocatedRequest
;
1221 if (Progress
== NULL
|| Results
== NULL
) {
1222 return EFI_INVALID_PARAMETER
;
1225 AllocatedRequest
= FALSE
;
1226 ConfigRequestHdr
= NULL
;
1227 ConfigRequest
= NULL
;
1230 Private
= TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This
);
1232 BufferSize
= sizeof (TLS_AUTH_CONFIG_IFR_NVDATA
);
1233 ZeroMem (&Private
->TlsAuthConfigNvData
, BufferSize
);
1235 *Progress
= Request
;
1237 if ((Request
!= NULL
) && !HiiIsConfigHdrMatch (Request
, &gTlsAuthConfigGuid
, mTlsAuthConfigStorageName
)) {
1238 return EFI_NOT_FOUND
;
1241 ConfigRequest
= Request
;
1242 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
1244 // Request is set to NULL or OFFSET is NULL, construct full request string.
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
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
;
1259 Status
= gHiiConfigRouting
->BlockToConfig (
1262 (UINT8
*) &Private
->TlsAuthConfigNvData
,
1269 // Free the allocated config request string.
1271 if (AllocatedRequest
) {
1272 FreePool (ConfigRequest
);
1276 // Set Progress string to the original request string.
1278 if (Request
== NULL
) {
1280 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
1281 *Progress
= Request
+ StrLen (Request
);
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
1298 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1300 @param Configuration A null-terminated Unicode string in
1301 <ConfigString> format.
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 beginn ing of the string if the failure
1307 is in the first name / value pair) or
1308 the terminating NULL if all was
1311 @retval EFI_SUCCESS The results have been distributed or are
1312 awaiting distribution.
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
1319 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
1320 Results parameter would result
1321 in this type of error.
1323 @retval EFI_NOT_FOUND Target for the specified routing data
1329 TlsAuthConfigAccessRouteConfig (
1330 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1331 IN CONST EFI_STRING Configuration
,
1332 OUT EFI_STRING
*Progress
1337 TLS_AUTH_CONFIG_PRIVATE_DATA
*Private
;
1339 if (Progress
== NULL
) {
1340 return EFI_INVALID_PARAMETER
;
1342 *Progress
= Configuration
;
1344 if (Configuration
== NULL
) {
1345 return EFI_INVALID_PARAMETER
;
1349 // Check routing data in <ConfigHdr>.
1350 // Note: there is no name for Name/Value storage, only GUID will be checked
1352 if (!HiiIsConfigHdrMatch (Configuration
, &gTlsAuthConfigGuid
, mTlsAuthConfigStorageName
)) {
1353 return EFI_NOT_FOUND
;
1356 Private
= TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This
);
1358 BufferSize
= sizeof (TLS_AUTH_CONFIG_IFR_NVDATA
);
1359 ZeroMem (&Private
->TlsAuthConfigNvData
, BufferSize
);
1361 Status
= gHiiConfigRouting
->ConfigToBlock (
1364 (UINT8
*) &Private
->TlsAuthConfigNvData
,
1368 if (EFI_ERROR (Status
)) {
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.
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
1390 @param ActionRequest On return, points to the action requested by the
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
1402 TlsAuthConfigAccessCallback (
1403 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1404 IN EFI_BROWSER_ACTION Action
,
1405 IN EFI_QUESTION_ID QuestionId
,
1407 IN OUT EFI_IFR_TYPE_VALUE
*Value
,
1408 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1413 RETURN_STATUS RStatus
;
1414 TLS_AUTH_CONFIG_PRIVATE_DATA
*Private
;
1416 TLS_AUTH_CONFIG_IFR_NVDATA
*IfrNvData
;
1418 EFI_DEVICE_PATH_PROTOCOL
*File
;
1420 Status
= EFI_SUCCESS
;
1423 if ((This
== NULL
) || (Value
== NULL
) || (ActionRequest
== NULL
)) {
1424 return EFI_INVALID_PARAMETER
;
1427 Private
= TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This
);
1429 mTlsAuthPrivateData
= Private
;
1432 // Retrieve uncommitted data from Browser
1434 BufferSize
= sizeof (TLS_AUTH_CONFIG_IFR_NVDATA
);
1435 IfrNvData
= AllocateZeroPool (BufferSize
);
1436 if (IfrNvData
== NULL
) {
1437 return EFI_OUT_OF_RESOURCES
;
1440 HiiGetBrowserData (&gTlsAuthConfigGuid
, mTlsAuthConfigStorageName
, BufferSize
, (UINT8
*) IfrNvData
);
1442 if ((Action
!= EFI_BROWSER_ACTION_CHANGED
) &&
1443 (Action
!= EFI_BROWSER_ACTION_CHANGING
) &&
1444 (Action
!= EFI_BROWSER_ACTION_FORM_CLOSE
)) {
1445 Status
= EFI_UNSUPPORTED
;
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
:
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
;
1463 if (QuestionId
== KEY_TLS_AUTH_CONFIG_CLIENT_CERT
) {
1464 LabelId
= TLS_AUTH_CONFIG_FORMID3_FORM
;
1466 LabelId
= TLS_AUTH_CONFIG_FORMID4_FORM
;
1470 // Refresh selected file.
1472 CleanUpPage (LabelId
, Private
);
1474 case KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE
:
1476 // If the file is already opened, clean the file related resource first.
1478 CleanFileContext (Private
);
1480 ChooseFile( NULL
, NULL
, UpdateCAFromFile
, &File
);
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
);
1489 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1491 L
"ERROR: Enroll Cert Failure!",
1497 case KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT
:
1498 CleanFileContext (Private
);
1500 if (Private
->CertGuid
!= NULL
) {
1501 FreePool (Private
->CertGuid
);
1502 Private
->CertGuid
= NULL
;
1506 case KEY_TLS_AUTH_CONFIG_DELETE_CERT
:
1509 EFI_TLS_CA_CERTIFICATE_VARIABLE
,
1510 &gEfiTlsCaCertificateGuid
,
1512 TLS_AUTH_CONFIG_FORMID5_FORM
,
1513 OPTION_DEL_CA_ESTION_ID
1518 if ((QuestionId
>= OPTION_DEL_CA_ESTION_ID
) &&
1519 (QuestionId
< (OPTION_DEL_CA_ESTION_ID
+ OPTION_CONFIG_RANGE
))) {
1522 EFI_TLS_CA_CERTIFICATE_VARIABLE
,
1523 &gEfiTlsCaCertificateGuid
,
1525 TLS_AUTH_CONFIG_FORMID5_FORM
,
1526 OPTION_DEL_CA_ESTION_ID
,
1527 QuestionId
- OPTION_DEL_CA_ESTION_ID
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
,
1540 if (RETURN_ERROR (RStatus
) || (IfrNvData
->CertGuid
[GUID_STRING_LENGTH
] != L
'\0')) {
1541 Status
= EFI_INVALID_PARAMETER
;
1545 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
1550 } else if (Action
== EFI_BROWSER_ACTION_FORM_CLOSE
) {
1551 CleanFileContext (Private
);
1556 if (!EFI_ERROR (Status
)) {
1557 BufferSize
= sizeof (TLS_AUTH_CONFIG_IFR_NVDATA
);
1558 HiiSetBrowserData (&gTlsAuthConfigGuid
, mTlsAuthConfigStorageName
, BufferSize
, (UINT8
*) IfrNvData
, NULL
);
1561 FreePool (IfrNvData
);