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 signature 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 resource 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
;
673 Status
= ReadFileContent (
674 Private
->FileContext
->FHandle
,
679 if (EFI_ERROR (Status
)) {
682 ASSERT (X509Data
!= NULL
);
684 SigDataSize
= sizeof(EFI_SIGNATURE_LIST
) + sizeof(EFI_SIGNATURE_DATA
) - 1 + X509DataSize
;
686 Data
= AllocateZeroPool (SigDataSize
);
688 Status
= EFI_OUT_OF_RESOURCES
;
693 // Fill Certificate Database parameters.
695 CACert
= (EFI_SIGNATURE_LIST
*) Data
;
696 CACert
->SignatureListSize
= (UINT32
) SigDataSize
;
697 CACert
->SignatureHeaderSize
= 0;
698 CACert
->SignatureSize
= (UINT32
) (sizeof(EFI_SIGNATURE_DATA
) - 1 + X509DataSize
);
699 CopyGuid (&CACert
->SignatureType
, &gEfiCertX509Guid
);
701 CACertData
= (EFI_SIGNATURE_DATA
*) ((UINT8
* ) CACert
+ sizeof (EFI_SIGNATURE_LIST
));
702 CopyGuid (&CACertData
->SignatureOwner
, Private
->CertGuid
);
703 CopyMem ((UINT8
* ) (CACertData
->SignatureData
), X509Data
, X509DataSize
);
706 // Check if the signature database entry already exists. If it does, use the
707 // EFI_VARIABLE_APPEND_WRITE attribute to append the new signature data to
708 // the original variable, plus preserve the original variable attributes.
710 Status
= gRT
->GetVariable(
712 &gEfiTlsCaCertificateGuid
,
717 if (Status
== EFI_BUFFER_TOO_SMALL
) {
718 Attr
|= EFI_VARIABLE_APPEND_WRITE
;
719 } else if (Status
== EFI_NOT_FOUND
) {
720 Attr
= TLS_AUTH_CONFIG_VAR_BASE_ATTR
;
725 Status
= gRT
->SetVariable(
727 &gEfiTlsCaCertificateGuid
,
732 if (EFI_ERROR (Status
)) {
737 CleanFileContext (Private
);
739 if (Private
->CertGuid
!= NULL
) {
740 FreePool (Private
->CertGuid
);
741 Private
->CertGuid
= NULL
;
748 if (X509Data
!= NULL
) {
756 Enroll Cert into TlsCaCertificate. The GUID will be Private->CertGuid.
758 @param[in] PrivateData The module's private data.
759 @param[in] VariableName Variable name of signature database.
761 @retval EFI_SUCCESS New Cert enrolled successfully.
762 @retval EFI_INVALID_PARAMETER The parameter is invalid.
763 @retval EFI_UNSUPPORTED The Cert file is unsupported type.
764 @retval others Fail to enroll Cert data.
769 IN TLS_AUTH_CONFIG_PRIVATE_DATA
*Private
,
770 IN CHAR16
*VariableName
776 if ((Private
->FileContext
->FileName
== NULL
) || (Private
->FileContext
->FHandle
== NULL
) || (Private
->CertGuid
== NULL
)) {
777 return EFI_INVALID_PARAMETER
;
781 // Parse the file's postfix.
783 NameLength
= StrLen (Private
->FileContext
->FileName
);
784 if (NameLength
<= 4) {
785 return EFI_INVALID_PARAMETER
;
787 FilePostFix
= Private
->FileContext
->FileName
+ NameLength
- 4;
789 if (IsDerPemEncodeCertificate (FilePostFix
)) {
791 // Supports DER-encoded X509 certificate.
793 return EnrollX509toVariable (Private
, VariableName
);
796 return EFI_UNSUPPORTED
;
800 Refresh the global UpdateData structure.
809 // Free current updated date
811 if (mStartOpCodeHandle
!= NULL
) {
812 HiiFreeOpCodeHandle (mStartOpCodeHandle
);
816 // Create new OpCode Handle
818 mStartOpCodeHandle
= HiiAllocateOpCodeHandle ();
821 // Create Hii Extend Label OpCode as the start opcode
823 mStartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
827 sizeof (EFI_IFR_GUID_LABEL
)
829 mStartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
833 Clean up the dynamic opcode at label and form specified by both LabelId.
835 @param[in] LabelId It is both the Form ID and Label ID for opcode deletion.
836 @param[in] PrivateData Module private data.
842 IN TLS_AUTH_CONFIG_PRIVATE_DATA
*PrivateData
845 RefreshUpdateData ();
848 // Remove all op-codes from dynamic page
850 mStartLabel
->Number
= LabelId
;
852 PrivateData
->RegisteredHandle
,
855 mStartOpCodeHandle
, // Label LabelId
856 mEndOpCodeHandle
// LABEL_END
861 Update the form base on the selected file.
863 @param FilePath Point to the file path.
864 @param FormId The form need to display.
866 @retval TRUE Exit caller function.
867 @retval FALSE Not exit caller function.
872 IN EFI_DEVICE_PATH_PROTOCOL
*FilePath
,
873 IN EFI_FORM_ID FormId
877 EFI_STRING_ID StringToken
;
881 if (FilePath
!= NULL
) {
882 FileName
= ExtractFileNameFromDevicePath(FilePath
);
884 if (FileName
== NULL
) {
886 // FileName = NULL has two case:
887 // 1. FilePath == NULL, not select file.
888 // 2. FilePath != NULL, but ExtractFileNameFromDevicePath return NULL not enough memory resource.
889 // In these two case, no need to update the form, and exit the caller function.
893 StringToken
= HiiSetString (mTlsAuthPrivateData
->RegisteredHandle
, 0, FileName
, NULL
);
895 mTlsAuthPrivateData
->FileContext
->FileName
= FileName
;
897 EfiOpenFileByDevicePath (
899 &mTlsAuthPrivateData
->FileContext
->FHandle
,
904 // Create Subtitle op-code for the display string of the option.
906 RefreshUpdateData ();
907 mStartLabel
->Number
= FormId
;
909 HiiCreateSubTitleOpCode (
918 mTlsAuthPrivateData
->RegisteredHandle
,
921 mStartOpCodeHandle
, /// Label FormId
922 mEndOpCodeHandle
/// LABEL_END
929 Update the form base on the input file path info.
931 @param FilePath Point to the file path.
933 @retval TRUE Exit caller function.
934 @retval FALSE Not exit caller function.
939 IN EFI_DEVICE_PATH_PROTOCOL
*FilePath
942 return UpdatePage(FilePath
, TLS_AUTH_CONFIG_FORMID4_FORM
);
946 Unload the configuration form, this includes: delete all the configuration
947 entries, uninstall the form callback protocol, and free the resources used.
949 @param[in] Private Pointer to the driver private data.
951 @retval EFI_SUCCESS The configuration form is unloaded.
952 @retval Others Failed to unload the form.
956 TlsAuthConfigFormUnload (
957 IN TLS_AUTH_CONFIG_PRIVATE_DATA
*Private
960 if (Private
->DriverHandle
!= NULL
) {
962 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
964 gBS
->UninstallMultipleProtocolInterfaces (
965 Private
->DriverHandle
,
966 &gEfiDevicePathProtocolGuid
,
967 &mTlsAuthConfigHiiVendorDevicePath
,
968 &gEfiHiiConfigAccessProtocolGuid
,
969 &Private
->ConfigAccess
,
972 Private
->DriverHandle
= NULL
;
975 if (Private
->RegisteredHandle
!= NULL
) {
977 // Remove HII package list
979 HiiRemovePackages (Private
->RegisteredHandle
);
980 Private
->RegisteredHandle
= NULL
;
983 if (Private
->CertGuid
!= NULL
) {
984 FreePool (Private
->CertGuid
);
987 if (Private
->FileContext
!= NULL
) {
988 FreePool (Private
->FileContext
);
993 if (mStartOpCodeHandle
!= NULL
) {
994 HiiFreeOpCodeHandle (mStartOpCodeHandle
);
997 if (mEndOpCodeHandle
!= NULL
) {
998 HiiFreeOpCodeHandle (mEndOpCodeHandle
);
1006 Initialize the configuration form.
1008 @param[in] Private Pointer to the driver private data.
1010 @retval EFI_SUCCESS The configuration form is initialized.
1011 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1015 TlsAuthConfigFormInit (
1016 IN TLS_AUTH_CONFIG_PRIVATE_DATA
*Private
1021 Private
->Signature
= TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE
;
1023 Private
->ConfigAccess
.ExtractConfig
= TlsAuthConfigAccessExtractConfig
;
1024 Private
->ConfigAccess
.RouteConfig
= TlsAuthConfigAccessRouteConfig
;
1025 Private
->ConfigAccess
.Callback
= TlsAuthConfigAccessCallback
;
1028 // Install Device Path Protocol and Config Access protocol to driver handle.
1030 Status
= gBS
->InstallMultipleProtocolInterfaces (
1031 &Private
->DriverHandle
,
1032 &gEfiDevicePathProtocolGuid
,
1033 &mTlsAuthConfigHiiVendorDevicePath
,
1034 &gEfiHiiConfigAccessProtocolGuid
,
1035 &Private
->ConfigAccess
,
1038 if (EFI_ERROR (Status
)) {
1043 // Publish our HII data.
1045 Private
->RegisteredHandle
= HiiAddPackages (
1046 &gTlsAuthConfigGuid
,
1047 Private
->DriverHandle
,
1048 TlsAuthConfigDxeStrings
,
1049 TlsAuthConfigVfrBin
,
1052 if (Private
->RegisteredHandle
== NULL
) {
1053 Status
= EFI_OUT_OF_RESOURCES
;
1057 Private
->FileContext
= AllocateZeroPool (sizeof (TLS_AUTH_CONFIG_FILE_CONTEXT
));
1058 if (Private
->FileContext
== NULL
) {
1059 Status
= EFI_OUT_OF_RESOURCES
;
1064 // Init OpCode Handle and Allocate space for creation of Buffer
1066 mStartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1067 if (mStartOpCodeHandle
== NULL
) {
1068 Status
= EFI_OUT_OF_RESOURCES
;
1072 mEndOpCodeHandle
= HiiAllocateOpCodeHandle ();
1073 if (mEndOpCodeHandle
== NULL
) {
1074 Status
= EFI_OUT_OF_RESOURCES
;
1079 // Create Hii Extend Label OpCode as the start opcode
1081 mStartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
1085 sizeof (EFI_IFR_GUID_LABEL
)
1087 mStartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1090 // Create Hii Extend Label OpCode as the end opcode
1092 mEndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
1096 sizeof (EFI_IFR_GUID_LABEL
)
1098 mEndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1099 mEndLabel
->Number
= LABEL_END
;
1104 TlsAuthConfigFormUnload (Private
);
1110 This function allows the caller to request the current
1111 configuration for one or more named elements. The resulting
1112 string is in <ConfigAltResp> format. Any and all alternative
1113 configuration strings shall also be appended to the end of the
1114 current configuration string. If they are, they must appear
1115 after the current configuration. They must contain the same
1116 routing (GUID, NAME, PATH) as the current configuration string.
1117 They must have an additional description indicating the type of
1118 alternative configuration the string represents,
1119 "ALTCFG=<StringToken>". That <StringToken> (when
1120 converted from Hex UNICODE to binary) is a reference to a
1121 string in the associated string pack.
1123 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1125 @param Request A null-terminated Unicode string in
1126 <ConfigRequest> format. Note that this
1127 includes the routing information as well as
1128 the configurable name / value pairs. It is
1129 invalid for this string to be in
1130 <MultiConfigRequest> format.
1131 If a NULL is passed in for the Request field,
1132 all of the settings being abstracted by this function
1133 will be returned in the Results field. In addition,
1134 if a ConfigHdr is passed in with no request elements,
1135 all of the settings being abstracted for that particular
1136 ConfigHdr reference will be returned in the Results Field.
1138 @param Progress On return, points to a character in the
1139 Request string. Points to the string's null
1140 terminator if request was successful. Points
1141 to the most recent "&" before the first
1142 failing name / value pair (or the beginning
1143 of the string if the failure is in the first
1144 name / value pair) if the request was not
1147 @param Results A null-terminated Unicode string in
1148 <MultiConfigAltResp> format which has all values
1149 filled in for the names in the Request string.
1150 String to be allocated by the called function.
1152 @retval EFI_SUCCESS The Results string is filled with the
1153 values corresponding to all requested
1156 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
1157 parts of the results that must be
1158 stored awaiting possible future
1161 @retval EFI_NOT_FOUND Routing data doesn't match any
1162 known driver. Progress set to the
1163 first character in the routing header.
1164 Note: There is no requirement that the
1165 driver validate the routing data. It
1166 must skip the <ConfigHdr> in order to
1169 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
1170 to most recent "&" before the
1171 error or the beginning of the
1174 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
1175 to the & before the name in
1181 TlsAuthConfigAccessExtractConfig (
1182 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1183 IN CONST EFI_STRING Request
,
1184 OUT EFI_STRING
*Progress
,
1185 OUT EFI_STRING
*Results
1191 EFI_STRING ConfigRequest
;
1192 EFI_STRING ConfigRequestHdr
;
1193 TLS_AUTH_CONFIG_PRIVATE_DATA
*Private
;
1194 BOOLEAN AllocatedRequest
;
1196 if (Progress
== NULL
|| Results
== NULL
) {
1197 return EFI_INVALID_PARAMETER
;
1200 AllocatedRequest
= FALSE
;
1201 ConfigRequestHdr
= NULL
;
1202 ConfigRequest
= NULL
;
1205 Private
= TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This
);
1207 BufferSize
= sizeof (TLS_AUTH_CONFIG_IFR_NVDATA
);
1208 ZeroMem (&Private
->TlsAuthConfigNvData
, BufferSize
);
1210 *Progress
= Request
;
1212 if ((Request
!= NULL
) && !HiiIsConfigHdrMatch (Request
, &gTlsAuthConfigGuid
, mTlsAuthConfigStorageName
)) {
1213 return EFI_NOT_FOUND
;
1216 ConfigRequest
= Request
;
1217 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
1219 // Request is set to NULL or OFFSET is NULL, construct full request string.
1221 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1222 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
1224 ConfigRequestHdr
= HiiConstructConfigHdr (&gTlsAuthConfigGuid
, mTlsAuthConfigStorageName
, Private
->DriverHandle
);
1225 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
1226 ConfigRequest
= AllocateZeroPool (Size
);
1227 ASSERT (ConfigRequest
!= NULL
);
1228 AllocatedRequest
= TRUE
;
1229 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
1230 FreePool (ConfigRequestHdr
);
1231 ConfigRequestHdr
= NULL
;
1234 Status
= gHiiConfigRouting
->BlockToConfig (
1237 (UINT8
*) &Private
->TlsAuthConfigNvData
,
1244 // Free the allocated config request string.
1246 if (AllocatedRequest
) {
1247 FreePool (ConfigRequest
);
1251 // Set Progress string to the original request string.
1253 if (Request
== NULL
) {
1255 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
1256 *Progress
= Request
+ StrLen (Request
);
1264 This function applies changes in a driver's configuration.
1265 Input is a Configuration, which has the routing data for this
1266 driver followed by name / value configuration pairs. The driver
1267 must apply those pairs to its configurable storage. If the
1268 driver's configuration is stored in a linear block of data
1269 and the driver's name / value pairs are in <BlockConfig>
1270 format, it may use the ConfigToBlock helper function (above) to
1273 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1275 @param Configuration A null-terminated Unicode string in
1276 <ConfigString> format.
1278 @param Progress A pointer to a string filled in with the
1279 offset of the most recent '&' before the
1280 first failing name / value pair (or the
1281 beginning of the string if the failure
1282 is in the first name / value pair) or
1283 the terminating NULL if all was
1286 @retval EFI_SUCCESS The results have been distributed or are
1287 awaiting distribution.
1289 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
1290 parts of the results that must be
1291 stored awaiting possible future
1294 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
1295 Results parameter would result
1296 in this type of error.
1298 @retval EFI_NOT_FOUND Target for the specified routing data
1304 TlsAuthConfigAccessRouteConfig (
1305 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1306 IN CONST EFI_STRING Configuration
,
1307 OUT EFI_STRING
*Progress
1312 TLS_AUTH_CONFIG_PRIVATE_DATA
*Private
;
1314 if (Progress
== NULL
) {
1315 return EFI_INVALID_PARAMETER
;
1317 *Progress
= Configuration
;
1319 if (Configuration
== NULL
) {
1320 return EFI_INVALID_PARAMETER
;
1324 // Check routing data in <ConfigHdr>.
1325 // Note: there is no name for Name/Value storage, only GUID will be checked
1327 if (!HiiIsConfigHdrMatch (Configuration
, &gTlsAuthConfigGuid
, mTlsAuthConfigStorageName
)) {
1328 return EFI_NOT_FOUND
;
1331 Private
= TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This
);
1333 BufferSize
= sizeof (TLS_AUTH_CONFIG_IFR_NVDATA
);
1334 ZeroMem (&Private
->TlsAuthConfigNvData
, BufferSize
);
1336 Status
= gHiiConfigRouting
->ConfigToBlock (
1339 (UINT8
*) &Private
->TlsAuthConfigNvData
,
1343 if (EFI_ERROR (Status
)) {
1352 This function is called to provide results data to the driver.
1353 This data consists of a unique key that is used to identify
1354 which data is either being passed back or being asked for.
1356 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1357 @param Action Specifies the type of action taken by the browser.
1358 @param QuestionId A unique value which is sent to the original
1359 exporting driver so that it can identify the type
1360 of data to expect. The format of the data tends to
1361 vary based on the opcode that generated the callback.
1362 @param Type The type of value for the question.
1363 @param Value A pointer to the data being sent to the original
1365 @param ActionRequest On return, points to the action requested by the
1368 @retval EFI_SUCCESS The callback successfully handled the action.
1369 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1370 variable and its data.
1371 @retval EFI_DEVICE_ERROR The variable could not be saved.
1372 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1377 TlsAuthConfigAccessCallback (
1378 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1379 IN EFI_BROWSER_ACTION Action
,
1380 IN EFI_QUESTION_ID QuestionId
,
1382 IN OUT EFI_IFR_TYPE_VALUE
*Value
,
1383 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1387 RETURN_STATUS RStatus
;
1388 TLS_AUTH_CONFIG_PRIVATE_DATA
*Private
;
1390 TLS_AUTH_CONFIG_IFR_NVDATA
*IfrNvData
;
1392 EFI_DEVICE_PATH_PROTOCOL
*File
;
1393 EFI_HII_POPUP_PROTOCOL
*HiiPopUp
;
1394 EFI_HII_POPUP_SELECTION PopUpSelect
;
1396 Status
= EFI_SUCCESS
;
1399 if ((This
== NULL
) || (Value
== NULL
) || (ActionRequest
== NULL
)) {
1400 return EFI_INVALID_PARAMETER
;
1403 Private
= TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This
);
1405 mTlsAuthPrivateData
= Private
;
1406 Status
= gBS
->LocateProtocol (&gEfiHiiPopupProtocolGuid
, NULL
, (VOID
**) &HiiPopUp
);
1407 if (EFI_ERROR (Status
)) {
1408 DEBUG ((DEBUG_ERROR
, "Can't find Form PopUp protocol. Exit (%r)\n", Status
));
1413 // Retrieve uncommitted data from Browser
1415 BufferSize
= sizeof (TLS_AUTH_CONFIG_IFR_NVDATA
);
1416 IfrNvData
= AllocateZeroPool (BufferSize
);
1417 if (IfrNvData
== NULL
) {
1418 return EFI_OUT_OF_RESOURCES
;
1421 HiiGetBrowserData (&gTlsAuthConfigGuid
, mTlsAuthConfigStorageName
, BufferSize
, (UINT8
*) IfrNvData
);
1423 if ((Action
!= EFI_BROWSER_ACTION_CHANGED
) &&
1424 (Action
!= EFI_BROWSER_ACTION_CHANGING
) &&
1425 (Action
!= EFI_BROWSER_ACTION_FORM_CLOSE
)) {
1426 Status
= EFI_UNSUPPORTED
;
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
:
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
;
1444 if (QuestionId
== KEY_TLS_AUTH_CONFIG_CLIENT_CERT
) {
1445 LabelId
= TLS_AUTH_CONFIG_FORMID3_FORM
;
1447 LabelId
= TLS_AUTH_CONFIG_FORMID4_FORM
;
1451 // Refresh selected file.
1453 CleanUpPage (LabelId
, Private
);
1455 case KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE
:
1457 // If the file is already opened, clean the file related resource first.
1459 CleanFileContext (Private
);
1461 ChooseFile( NULL
, NULL
, UpdateCAFromFile
, &File
);
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
);
1469 HiiPopUp
->CreatePopup (
1471 EfiHiiPopupStyleError
,
1473 Private
->RegisteredHandle
,
1474 STRING_TOKEN (STR_TLS_AUTH_ENROLL_CERT_FAILURE
),
1480 case KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT
:
1481 CleanFileContext (Private
);
1483 if (Private
->CertGuid
!= NULL
) {
1484 FreePool (Private
->CertGuid
);
1485 Private
->CertGuid
= NULL
;
1489 case KEY_TLS_AUTH_CONFIG_DELETE_CERT
:
1492 EFI_TLS_CA_CERTIFICATE_VARIABLE
,
1493 &gEfiTlsCaCertificateGuid
,
1495 TLS_AUTH_CONFIG_FORMID5_FORM
,
1496 OPTION_DEL_CA_ESTION_ID
1501 if ((QuestionId
>= OPTION_DEL_CA_ESTION_ID
) &&
1502 (QuestionId
< (OPTION_DEL_CA_ESTION_ID
+ OPTION_CONFIG_RANGE
))) {
1505 EFI_TLS_CA_CERTIFICATE_VARIABLE
,
1506 &gEfiTlsCaCertificateGuid
,
1508 TLS_AUTH_CONFIG_FORMID5_FORM
,
1509 OPTION_DEL_CA_ESTION_ID
,
1510 QuestionId
- OPTION_DEL_CA_ESTION_ID
1515 } else if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
1516 switch (QuestionId
) {
1517 case KEY_TLS_AUTH_CONFIG_CERT_GUID
:
1518 ASSERT (Private
->CertGuid
!= NULL
);
1519 RStatus
= StrToGuid (
1520 IfrNvData
->CertGuid
,
1523 if (RETURN_ERROR (RStatus
) || (IfrNvData
->CertGuid
[GUID_STRING_LENGTH
] != L
'\0')) {
1524 Status
= EFI_INVALID_PARAMETER
;
1528 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
1533 } else if (Action
== EFI_BROWSER_ACTION_FORM_CLOSE
) {
1534 CleanFileContext (Private
);
1539 if (!EFI_ERROR (Status
)) {
1540 BufferSize
= sizeof (TLS_AUTH_CONFIG_IFR_NVDATA
);
1541 HiiSetBrowserData (&gTlsAuthConfigGuid
, mTlsAuthConfigStorageName
, BufferSize
, (UINT8
*) IfrNvData
, NULL
);
1544 FreePool (IfrNvData
);