If the platform creates the "TlsCaCertificate" variable as volatile, then EnrollX509toVariable() shouldn't fail to extend it just because TLS_AUTH_CONFIG_VAR_BASE_ATTR contains the EFI_VARIABLE_NON_VOLATILE attribute. Thus, if the variable exists, add the EFI_VARIABLE_APPEND_WRITE attribute to the variable's current attributes. This is what DeleteCert() does already. Cc: Jiaxin Wu <jiaxin.wu@intel.com> Cc: Siyuan Fu <siyuan.fu@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Fu Siyuan <siyuan.fu@intel.com> Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
		
			
				
	
	
		
			1692 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1692 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   The Miscellaneous Routines for TlsAuthConfigDxe driver.
 | |
| 
 | |
| Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
 | |
| 
 | |
| This program and the accompanying materials
 | |
| are licensed and made available under the terms and conditions of the BSD License
 | |
| which accompanies this distribution.  The full text of the license may be found at
 | |
| http://opensource.org/licenses/bsd-license.php
 | |
| 
 | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include "TlsAuthConfigImpl.h"
 | |
| 
 | |
| VOID                    *mStartOpCodeHandle = NULL;
 | |
| VOID                    *mEndOpCodeHandle   = NULL;
 | |
| EFI_IFR_GUID_LABEL      *mStartLabel        = NULL;
 | |
| EFI_IFR_GUID_LABEL      *mEndLabel          = NULL;
 | |
| 
 | |
| 
 | |
| CHAR16                  mTlsAuthConfigStorageName[] = L"TLS_AUTH_CONFIG_IFR_NVDATA";
 | |
| 
 | |
| TLS_AUTH_CONFIG_PRIVATE_DATA      *mTlsAuthPrivateData = NULL;
 | |
| 
 | |
| HII_VENDOR_DEVICE_PATH  mTlsAuthConfigHiiVendorDevicePath = {
 | |
|   {
 | |
|     {
 | |
|       HARDWARE_DEVICE_PATH,
 | |
|       HW_VENDOR_DP,
 | |
|       {
 | |
|         (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
 | |
|         (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
 | |
|       }
 | |
|     },
 | |
|     TLS_AUTH_CONFIG_GUID
 | |
|   },
 | |
|   {
 | |
|     END_DEVICE_PATH_TYPE,
 | |
|     END_ENTIRE_DEVICE_PATH_SUBTYPE,
 | |
|     {
 | |
|       (UINT8) (END_DEVICE_PATH_LENGTH),
 | |
|       (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| //
 | |
| // Possible DER-encoded certificate file suffixes, end with NULL pointer.
 | |
| //
 | |
| CHAR16* mDerPemEncodedSuffix[] = {
 | |
|   L".cer",
 | |
|   L".der",
 | |
|   L".crt",
 | |
|   L".pem",
 | |
|   NULL
 | |
| };
 | |
| 
 | |
| /**
 | |
|   This code checks if the FileSuffix is one of the possible DER/PEM-encoded certificate suffix.
 | |
| 
 | |
|   @param[in] FileSuffix            The suffix of the input certificate file
 | |
| 
 | |
|   @retval    TRUE           It's a DER/PEM-encoded certificate.
 | |
|   @retval    FALSE          It's NOT a DER/PEM-encoded certificate.
 | |
| 
 | |
| **/
 | |
| BOOLEAN
 | |
| IsDerPemEncodeCertificate (
 | |
|   IN CONST CHAR16         *FileSuffix
 | |
| )
 | |
| {
 | |
|   UINTN     Index;
 | |
|   for (Index = 0; mDerPemEncodedSuffix[Index] != NULL; Index++) {
 | |
|     if (StrCmp (FileSuffix, mDerPemEncodedSuffix[Index]) == 0) {
 | |
|       return TRUE;
 | |
|     }
 | |
|   }
 | |
|   return FALSE;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Worker function that prints an EFI_GUID into specified Buffer.
 | |
| 
 | |
|   @param[in]     Guid          Pointer to GUID to print.
 | |
|   @param[in]     Buffer        Buffer to print Guid into.
 | |
|   @param[in]     BufferSize    Size of Buffer.
 | |
| 
 | |
|   @retval    Number of characters printed.
 | |
| 
 | |
| **/
 | |
| UINTN
 | |
| GuidToString (
 | |
|   IN  EFI_GUID  *Guid,
 | |
|   IN  CHAR16    *Buffer,
 | |
|   IN  UINTN     BufferSize
 | |
|   )
 | |
| {
 | |
|   return UnicodeSPrint (
 | |
|            Buffer,
 | |
|            BufferSize,
 | |
|            L"%g",
 | |
|            Guid
 | |
|            );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   List all cert in specified database by GUID in the page
 | |
|   for user to select and delete as needed.
 | |
| 
 | |
|   @param[in]    PrivateData         Module's private data.
 | |
|   @param[in]    VariableName        The variable name of the vendor's signature database.
 | |
|   @param[in]    VendorGuid          A unique identifier for the vendor.
 | |
|   @param[in]    LabelNumber         Label number to insert opcodes.
 | |
|   @param[in]    FormId              Form ID of current page.
 | |
|   @param[in]    QuestionIdBase      Base question id of the signature list.
 | |
| 
 | |
|   @retval   EFI_SUCCESS             Success to update the signature list page
 | |
|   @retval   EFI_OUT_OF_RESOURCES    Unable to allocate required resources.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| UpdateDeletePage (
 | |
|   IN TLS_AUTH_CONFIG_PRIVATE_DATA     *Private,
 | |
|   IN CHAR16                           *VariableName,
 | |
|   IN EFI_GUID                         *VendorGuid,
 | |
|   IN UINT16                           LabelNumber,
 | |
|   IN EFI_FORM_ID                      FormId,
 | |
|   IN EFI_QUESTION_ID                  QuestionIdBase
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                  Status;
 | |
|   UINT32                      Index;
 | |
|   UINTN                       CertCount;
 | |
|   UINTN                       GuidIndex;
 | |
|   VOID                        *StartOpCodeHandle;
 | |
|   VOID                        *EndOpCodeHandle;
 | |
|   EFI_IFR_GUID_LABEL          *StartLabel;
 | |
|   EFI_IFR_GUID_LABEL          *EndLabel;
 | |
|   UINTN                       DataSize;
 | |
|   UINT8                       *Data;
 | |
|   EFI_SIGNATURE_LIST          *CertList;
 | |
|   EFI_SIGNATURE_DATA          *Cert;
 | |
|   UINT32                      ItemDataSize;
 | |
|   CHAR16                      *GuidStr;
 | |
|   EFI_STRING_ID               GuidID;
 | |
|   EFI_STRING_ID               Help;
 | |
| 
 | |
|   Data     = NULL;
 | |
|   CertList = NULL;
 | |
|   Cert     = NULL;
 | |
|   GuidStr  = NULL;
 | |
|   StartOpCodeHandle = NULL;
 | |
|   EndOpCodeHandle   = NULL;
 | |
| 
 | |
|   //
 | |
|   // Initialize the container for dynamic opcodes.
 | |
|   //
 | |
|   StartOpCodeHandle = HiiAllocateOpCodeHandle ();
 | |
|   if (StartOpCodeHandle == NULL) {
 | |
|     Status = EFI_OUT_OF_RESOURCES;
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   EndOpCodeHandle = HiiAllocateOpCodeHandle ();
 | |
|   if (EndOpCodeHandle == NULL) {
 | |
|     Status = EFI_OUT_OF_RESOURCES;
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Create Hii Extend Label OpCode.
 | |
|   //
 | |
|   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
 | |
|                                         StartOpCodeHandle,
 | |
|                                         &gEfiIfrTianoGuid,
 | |
|                                         NULL,
 | |
|                                         sizeof (EFI_IFR_GUID_LABEL)
 | |
|                                         );
 | |
|   StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
 | |
|   StartLabel->Number        = LabelNumber;
 | |
| 
 | |
|   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
 | |
|                                       EndOpCodeHandle,
 | |
|                                       &gEfiIfrTianoGuid,
 | |
|                                       NULL,
 | |
|                                       sizeof (EFI_IFR_GUID_LABEL)
 | |
|                                       );
 | |
|   EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
 | |
|   EndLabel->Number        = LABEL_END;
 | |
| 
 | |
|   //
 | |
|   // Read Variable.
 | |
|   //
 | |
|   DataSize = 0;
 | |
|   Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data);
 | |
|   if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   Data = (UINT8 *) AllocateZeroPool (DataSize);
 | |
|   if (Data == NULL) {
 | |
|     Status = EFI_OUT_OF_RESOURCES;
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   GuidStr = AllocateZeroPool (100);
 | |
|   if (GuidStr == NULL) {
 | |
|     Status = EFI_OUT_OF_RESOURCES;
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Enumerate all data.
 | |
|   //
 | |
|   ItemDataSize = (UINT32) DataSize;
 | |
|   CertList = (EFI_SIGNATURE_LIST *) Data;
 | |
|   GuidIndex = 0;
 | |
| 
 | |
|   while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
 | |
| 
 | |
|     if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
 | |
|       Help = STRING_TOKEN (STR_CERT_TYPE_PCKS_GUID);
 | |
|     } else {
 | |
|       //
 | |
|       // The signature type is not supported in current implementation.
 | |
|       //
 | |
|       ItemDataSize -= CertList->SignatureListSize;
 | |
|       CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
 | |
|       continue;
 | |
|     }
 | |
| 
 | |
|     CertCount  = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
 | |
|     for (Index = 0; Index < CertCount; Index++) {
 | |
|       Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList
 | |
|                                               + sizeof (EFI_SIGNATURE_LIST)
 | |
|                                               + CertList->SignatureHeaderSize
 | |
|                                               + Index * CertList->SignatureSize);
 | |
|       //
 | |
|       // Display GUID and help
 | |
|       //
 | |
|       GuidToString (&Cert->SignatureOwner, GuidStr, 100);
 | |
|       GuidID  = HiiSetString (Private->RegisteredHandle, 0, GuidStr, NULL);
 | |
|       HiiCreateCheckBoxOpCode (
 | |
|         StartOpCodeHandle,
 | |
|         (EFI_QUESTION_ID) (QuestionIdBase + GuidIndex++),
 | |
|         0,
 | |
|         0,
 | |
|         GuidID,
 | |
|         Help,
 | |
|         EFI_IFR_FLAG_CALLBACK,
 | |
|         0,
 | |
|         NULL
 | |
|         );
 | |
|     }
 | |
| 
 | |
|     ItemDataSize -= CertList->SignatureListSize;
 | |
|     CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
 | |
|   }
 | |
| 
 | |
| ON_EXIT:
 | |
|   HiiUpdateForm (
 | |
|     Private->RegisteredHandle,
 | |
|     &gTlsAuthConfigGuid,
 | |
|     FormId,
 | |
|     StartOpCodeHandle,
 | |
|     EndOpCodeHandle
 | |
|     );
 | |
| 
 | |
|   if (StartOpCodeHandle != NULL) {
 | |
|     HiiFreeOpCodeHandle (StartOpCodeHandle);
 | |
|   }
 | |
| 
 | |
|   if (EndOpCodeHandle != NULL) {
 | |
|     HiiFreeOpCodeHandle (EndOpCodeHandle);
 | |
|   }
 | |
| 
 | |
|   if (Data != NULL) {
 | |
|     FreePool (Data);
 | |
|   }
 | |
| 
 | |
|   if (GuidStr != NULL) {
 | |
|     FreePool (GuidStr);
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Delete one entry from cert database.
 | |
| 
 | |
|   @param[in]    Private             Module's private data.
 | |
|   @param[in]    VariableName        The variable name of the database.
 | |
|   @param[in]    VendorGuid          A unique identifier for the vendor.
 | |
|   @param[in]    LabelNumber         Label number to insert opcodes.
 | |
|   @param[in]    FormId              Form ID of current page.
 | |
|   @param[in]    QuestionIdBase      Base question id of the cert list.
 | |
|   @param[in]    DeleteIndex         Cert index to delete.
 | |
| 
 | |
|   @retval   EFI_SUCCESS             Delete siganture successfully.
 | |
|   @retval   EFI_NOT_FOUND           Can't find the signature item,
 | |
|   @retval   EFI_OUT_OF_RESOURCES    Could not allocate needed resources.
 | |
| **/
 | |
| EFI_STATUS
 | |
| DeleteCert (
 | |
|   IN TLS_AUTH_CONFIG_PRIVATE_DATA     *Private,
 | |
|   IN CHAR16                           *VariableName,
 | |
|   IN EFI_GUID                         *VendorGuid,
 | |
|   IN UINT16                           LabelNumber,
 | |
|   IN EFI_FORM_ID                      FormId,
 | |
|   IN EFI_QUESTION_ID                  QuestionIdBase,
 | |
|   IN UINTN                            DeleteIndex
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                  Status;
 | |
|   UINTN                       DataSize;
 | |
|   UINT8                       *Data;
 | |
|   UINT8                       *OldData;
 | |
|   UINT32                      Attr;
 | |
|   UINT32                      Index;
 | |
|   EFI_SIGNATURE_LIST          *CertList;
 | |
|   EFI_SIGNATURE_LIST          *NewCertList;
 | |
|   EFI_SIGNATURE_DATA          *Cert;
 | |
|   UINTN                       CertCount;
 | |
|   UINT32                      Offset;
 | |
|   BOOLEAN                     IsItemFound;
 | |
|   UINT32                      ItemDataSize;
 | |
|   UINTN                       GuidIndex;
 | |
| 
 | |
|   Data            = NULL;
 | |
|   OldData         = NULL;
 | |
|   CertList        = NULL;
 | |
|   Cert            = NULL;
 | |
|   Attr            = 0;
 | |
| 
 | |
|   //
 | |
|   // Get original signature list data.
 | |
|   //
 | |
|   DataSize = 0;
 | |
|   Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, NULL);
 | |
|   if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   OldData = (UINT8 *) AllocateZeroPool (DataSize);
 | |
|   if (OldData == NULL) {
 | |
|     Status = EFI_OUT_OF_RESOURCES;
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   Status = gRT->GetVariable (VariableName, VendorGuid, &Attr, &DataSize, OldData);
 | |
|   if (EFI_ERROR(Status)) {
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Allocate space for new variable.
 | |
|   //
 | |
|   Data = (UINT8*) AllocateZeroPool (DataSize);
 | |
|   if (Data == NULL) {
 | |
|     Status  =  EFI_OUT_OF_RESOURCES;
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Enumerate all data and erasing the target item.
 | |
|   //
 | |
|   IsItemFound = FALSE;
 | |
|   ItemDataSize = (UINT32) DataSize;
 | |
|   CertList = (EFI_SIGNATURE_LIST *) OldData;
 | |
|   Offset = 0;
 | |
|   GuidIndex = 0;
 | |
|   while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
 | |
|     if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
 | |
|       //
 | |
|       // Copy EFI_SIGNATURE_LIST header then calculate the signature count in this list.
 | |
|       //
 | |
|       CopyMem (Data + Offset, CertList, (sizeof(EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize));
 | |
|       NewCertList = (EFI_SIGNATURE_LIST*) (Data + Offset);
 | |
|       Offset += (sizeof(EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
 | |
|       Cert      = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
 | |
|       CertCount  = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
 | |
|       for (Index = 0; Index < CertCount; Index++) {
 | |
|         if (GuidIndex == DeleteIndex) {
 | |
|           //
 | |
|           // Find it! Skip it!
 | |
|           //
 | |
|           NewCertList->SignatureListSize -= CertList->SignatureSize;
 | |
|           IsItemFound = TRUE;
 | |
|         } else {
 | |
|           //
 | |
|           // This item doesn't match. Copy it to the Data buffer.
 | |
|           //
 | |
|           CopyMem (Data + Offset, (UINT8*)(Cert), CertList->SignatureSize);
 | |
|           Offset += CertList->SignatureSize;
 | |
|         }
 | |
|         GuidIndex++;
 | |
|         Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
 | |
|       }
 | |
|     } else {
 | |
|       //
 | |
|       // This List doesn't match. Just copy it to the Data buffer.
 | |
|       //
 | |
|       CopyMem (Data + Offset, (UINT8*)(CertList), CertList->SignatureListSize);
 | |
|       Offset += CertList->SignatureListSize;
 | |
|     }
 | |
| 
 | |
|     ItemDataSize -= CertList->SignatureListSize;
 | |
|     CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
 | |
|   }
 | |
| 
 | |
|   if (!IsItemFound) {
 | |
|     //
 | |
|     // Doesn't find the signature Item!
 | |
|     //
 | |
|     Status = EFI_NOT_FOUND;
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Delete the EFI_SIGNATURE_LIST header if there is no signature in the list.
 | |
|   //
 | |
|   ItemDataSize = Offset;
 | |
|   CertList = (EFI_SIGNATURE_LIST *) Data;
 | |
|   Offset = 0;
 | |
|   ZeroMem (OldData, ItemDataSize);
 | |
|   while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
 | |
|     CertCount  = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
 | |
|     DEBUG ((DEBUG_INFO, "       CertCount = %x\n", CertCount));
 | |
|     if (CertCount != 0) {
 | |
|       CopyMem (OldData + Offset, (UINT8*)(CertList), CertList->SignatureListSize);
 | |
|       Offset += CertList->SignatureListSize;
 | |
|     }
 | |
|     ItemDataSize -= CertList->SignatureListSize;
 | |
|     CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
 | |
|   }
 | |
| 
 | |
|   DataSize = Offset;
 | |
| 
 | |
|   Status = gRT->SetVariable(
 | |
|                   VariableName,
 | |
|                   VendorGuid,
 | |
|                   Attr,
 | |
|                   DataSize,
 | |
|                   OldData
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     DEBUG ((DEBUG_ERROR, "Failed to set variable, Status = %r\n", Status));
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
| ON_EXIT:
 | |
|   if (Data != NULL) {
 | |
|     FreePool(Data);
 | |
|   }
 | |
| 
 | |
|   if (OldData != NULL) {
 | |
|     FreePool(OldData);
 | |
|   }
 | |
| 
 | |
|   return UpdateDeletePage (
 | |
|            Private,
 | |
|            VariableName,
 | |
|            VendorGuid,
 | |
|            LabelNumber,
 | |
|            FormId,
 | |
|            QuestionIdBase
 | |
|            );
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Clean the file related resource.
 | |
| 
 | |
|   @param[in]    Private             Module's private data.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| CleanFileContext (
 | |
|   IN TLS_AUTH_CONFIG_PRIVATE_DATA     *Private
 | |
|   )
 | |
| {
 | |
|   if (Private->FileContext->FHandle != NULL) {
 | |
|     Private->FileContext->FHandle->Close (Private->FileContext->FHandle);
 | |
|     Private->FileContext->FHandle = NULL;
 | |
|     if (Private->FileContext->FileName!= NULL){
 | |
|       FreePool(Private->FileContext->FileName);
 | |
|       Private->FileContext->FileName = NULL;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Read file content into BufferPtr, the size of the allocate buffer
 | |
|   is *FileSize plus AddtionAllocateSize.
 | |
| 
 | |
|   @param[in]       FileHandle            The file to be read.
 | |
|   @param[in, out]  BufferPtr             Pointers to the pointer of allocated buffer.
 | |
|   @param[out]      FileSize              Size of input file
 | |
|   @param[in]       AddtionAllocateSize   Addtion size the buffer need to be allocated.
 | |
|                                          In case the buffer need to contain others besides the file content.
 | |
| 
 | |
|   @retval   EFI_SUCCESS                  The file was read into the buffer.
 | |
|   @retval   EFI_INVALID_PARAMETER        A parameter was invalid.
 | |
|   @retval   EFI_OUT_OF_RESOURCES         A memory allocation failed.
 | |
|   @retval   others                       Unexpected error.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| ReadFileContent (
 | |
|   IN      EFI_FILE_HANDLE           FileHandle,
 | |
|   IN OUT  VOID                      **BufferPtr,
 | |
|      OUT  UINTN                     *FileSize,
 | |
|   IN      UINTN                     AddtionAllocateSize
 | |
|   )
 | |
| 
 | |
| {
 | |
|   UINTN      BufferSize;
 | |
|   UINT64     SourceFileSize;
 | |
|   VOID       *Buffer;
 | |
|   EFI_STATUS Status;
 | |
| 
 | |
|   if ((FileHandle == NULL) || (FileSize == NULL)) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   Buffer = NULL;
 | |
| 
 | |
|   //
 | |
|   // Get the file size
 | |
|   //
 | |
|   Status = FileHandle->SetPosition (FileHandle, (UINT64) -1);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   Status = FileHandle->GetPosition (FileHandle, &SourceFileSize);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   Status = FileHandle->SetPosition (FileHandle, 0);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   BufferSize = (UINTN) SourceFileSize + AddtionAllocateSize;
 | |
|   Buffer =  AllocateZeroPool(BufferSize);
 | |
|   if (Buffer == NULL) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   BufferSize = (UINTN) SourceFileSize;
 | |
|   *FileSize  = BufferSize;
 | |
| 
 | |
|   Status = FileHandle->Read (FileHandle, &BufferSize, Buffer);
 | |
|   if (EFI_ERROR (Status) || BufferSize != *FileSize) {
 | |
|     FreePool (Buffer);
 | |
|     Buffer = NULL;
 | |
|     Status  = EFI_BAD_BUFFER_SIZE;
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
| ON_EXIT:
 | |
| 
 | |
|   *BufferPtr = Buffer;
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This function will open a file or directory referenced by DevicePath.
 | |
| 
 | |
|   This function opens a file with the open mode according to the file path. The
 | |
|   Attributes is valid only for EFI_FILE_MODE_CREATE.
 | |
| 
 | |
|   @param[in, out]  FilePath        On input, the device path to the file.
 | |
|                                    On output, the remaining device path.
 | |
|   @param[out]      FileHandle      Pointer to the file handle.
 | |
|   @param[in]       OpenMode        The mode to open the file with.
 | |
|   @param[in]       Attributes      The file's file attributes.
 | |
| 
 | |
|   @retval EFI_SUCCESS              The information was set.
 | |
|   @retval EFI_INVALID_PARAMETER    One of the parameters has an invalid value.
 | |
|   @retval EFI_UNSUPPORTED          Could not open the file path.
 | |
|   @retval EFI_NOT_FOUND            The specified file could not be found on the
 | |
|                                    device or the file system could not be found on
 | |
|                                    the device.
 | |
|   @retval EFI_NO_MEDIA             The device has no medium.
 | |
|   @retval EFI_MEDIA_CHANGED        The device has a different medium in it or the
 | |
|                                    medium is no longer supported.
 | |
|   @retval EFI_DEVICE_ERROR         The device reported an error.
 | |
|   @retval EFI_VOLUME_CORRUPTED     The file system structures are corrupted.
 | |
|   @retval EFI_WRITE_PROTECTED      The file or medium is write protected.
 | |
|   @retval EFI_ACCESS_DENIED        The file was opened read only.
 | |
|   @retval EFI_OUT_OF_RESOURCES     Not enough resources were available to open the
 | |
|                                    file.
 | |
|   @retval EFI_VOLUME_FULL          The volume is full.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| OpenFileByDevicePath (
 | |
|   IN OUT EFI_DEVICE_PATH_PROTOCOL     **FilePath,
 | |
|   OUT EFI_FILE_HANDLE                 *FileHandle,
 | |
|   IN UINT64                           OpenMode,
 | |
|   IN UINT64                           Attributes
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                      Status;
 | |
|   EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol;
 | |
|   EFI_FILE_PROTOCOL               *Handle1;
 | |
|   EFI_FILE_PROTOCOL               *Handle2;
 | |
|   EFI_HANDLE                      DeviceHandle;
 | |
| 
 | |
|   if ((FilePath == NULL || FileHandle == NULL)) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   Status = gBS->LocateDevicePath (
 | |
|                   &gEfiSimpleFileSystemProtocolGuid,
 | |
|                   FilePath,
 | |
|                   &DeviceHandle
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Status = gBS->OpenProtocol(
 | |
|                   DeviceHandle,
 | |
|                   &gEfiSimpleFileSystemProtocolGuid,
 | |
|                   (VOID**)&EfiSimpleFileSystemProtocol,
 | |
|                   gImageHandle,
 | |
|                   NULL,
 | |
|                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Status = EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystemProtocol, &Handle1);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     FileHandle = NULL;
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // go down directories one node at a time.
 | |
|   //
 | |
|   while (!IsDevicePathEnd (*FilePath)) {
 | |
|     //
 | |
|     // For file system access each node should be a file path component
 | |
|     //
 | |
|     if (DevicePathType    (*FilePath) != MEDIA_DEVICE_PATH ||
 | |
|         DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP
 | |
|        ) {
 | |
|       FileHandle = NULL;
 | |
|       return (EFI_INVALID_PARAMETER);
 | |
|     }
 | |
|     //
 | |
|     // Open this file path node
 | |
|     //
 | |
|     Handle2  = Handle1;
 | |
|     Handle1 = NULL;
 | |
| 
 | |
|     //
 | |
|     // Try to test opening an existing file
 | |
|     //
 | |
|     Status = Handle2->Open (
 | |
|                         Handle2,
 | |
|                         &Handle1,
 | |
|                         ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
 | |
|                         OpenMode &~EFI_FILE_MODE_CREATE,
 | |
|                         0
 | |
|                         );
 | |
| 
 | |
|     //
 | |
|     // see if the error was that it needs to be created
 | |
|     //
 | |
|     if ((EFI_ERROR (Status)) && (OpenMode != (OpenMode &~EFI_FILE_MODE_CREATE))) {
 | |
|       Status = Handle2->Open (
 | |
|                           Handle2,
 | |
|                           &Handle1,
 | |
|                           ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
 | |
|                           OpenMode,
 | |
|                           Attributes
 | |
|                           );
 | |
|     }
 | |
|     //
 | |
|     // Close the last node
 | |
|     //
 | |
|     Handle2->Close (Handle2);
 | |
| 
 | |
|     if (EFI_ERROR(Status)) {
 | |
|       return (Status);
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Get the next node
 | |
|     //
 | |
|     *FilePath = NextDevicePathNode (*FilePath);
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // This is a weak spot since if the undefined SHELL_FILE_HANDLE format changes this must change also!
 | |
|   //
 | |
|   *FileHandle = (VOID*)Handle1;
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This function converts an input device structure to a Unicode string.
 | |
| 
 | |
|   @param[in] DevPath                  A pointer to the device path structure.
 | |
| 
 | |
|   @return A new allocated Unicode string that represents the device path.
 | |
| 
 | |
| **/
 | |
| CHAR16 *
 | |
| EFIAPI
 | |
| DevicePathToStr (
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL     *DevPath
 | |
|   )
 | |
| {
 | |
|   return ConvertDevicePathToText (
 | |
|            DevPath,
 | |
|            FALSE,
 | |
|            TRUE
 | |
|            );
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Extract filename from device path. The returned buffer is allocated using AllocateCopyPool.
 | |
|   The caller is responsible for freeing the allocated buffer using FreePool(). If return NULL
 | |
|   means not enough memory resource.
 | |
| 
 | |
|   @param DevicePath       Device path.
 | |
| 
 | |
|   @retval NULL            Not enough memory resourece for AllocateCopyPool.
 | |
|   @retval Other           A new allocated string that represents the file name.
 | |
| 
 | |
| **/
 | |
| CHAR16 *
 | |
| ExtractFileNameFromDevicePath (
 | |
|   IN   EFI_DEVICE_PATH_PROTOCOL *DevicePath
 | |
|   )
 | |
| {
 | |
|   CHAR16          *String;
 | |
|   CHAR16          *MatchString;
 | |
|   CHAR16          *LastMatch;
 | |
|   CHAR16          *FileName;
 | |
|   UINTN           Length;
 | |
| 
 | |
|   ASSERT(DevicePath != NULL);
 | |
| 
 | |
|   String = DevicePathToStr(DevicePath);
 | |
|   MatchString = String;
 | |
|   LastMatch   = String;
 | |
|   FileName    = NULL;
 | |
| 
 | |
|   while(MatchString != NULL){
 | |
|     LastMatch   = MatchString + 1;
 | |
|     MatchString = StrStr(LastMatch,L"\\");
 | |
|   }
 | |
| 
 | |
|   Length = StrLen(LastMatch);
 | |
|   FileName = AllocateCopyPool ((Length + 1) * sizeof(CHAR16), LastMatch);
 | |
|   if (FileName != NULL) {
 | |
|     *(FileName + Length) = 0;
 | |
|   }
 | |
| 
 | |
|   FreePool(String);
 | |
| 
 | |
|   return FileName;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Enroll a new X509 certificate into Variable.
 | |
| 
 | |
|   @param[in] PrivateData     The module's private data.
 | |
|   @param[in] VariableName    Variable name of CA database.
 | |
| 
 | |
|   @retval   EFI_SUCCESS            New X509 is enrolled successfully.
 | |
|   @retval   EFI_OUT_OF_RESOURCES   Could not allocate needed resources.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EnrollX509toVariable (
 | |
|   IN TLS_AUTH_CONFIG_PRIVATE_DATA   *Private,
 | |
|   IN CHAR16                         *VariableName
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                        Status;
 | |
|   UINTN                             X509DataSize;
 | |
|   VOID                              *X509Data;
 | |
|   EFI_SIGNATURE_LIST                *CACert;
 | |
|   EFI_SIGNATURE_DATA                *CACertData;
 | |
|   VOID                              *Data;
 | |
|   UINTN                             DataSize;
 | |
|   UINTN                             SigDataSize;
 | |
|   UINT32                            Attr;
 | |
| 
 | |
|   X509DataSize  = 0;
 | |
|   SigDataSize   = 0;
 | |
|   DataSize      = 0;
 | |
|   X509Data      = NULL;
 | |
|   CACert        = NULL;
 | |
|   CACertData    = NULL;
 | |
|   Data          = NULL;
 | |
|   Attr          = 0;
 | |
| 
 | |
|   Status = ReadFileContent (
 | |
|              Private->FileContext->FHandle,
 | |
|              &X509Data,
 | |
|              &X509DataSize,
 | |
|              0
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
|   ASSERT (X509Data != NULL);
 | |
| 
 | |
|   SigDataSize = sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_SIGNATURE_DATA) - 1 + X509DataSize;
 | |
| 
 | |
|   Data = AllocateZeroPool (SigDataSize);
 | |
|   if (Data == NULL) {
 | |
|     Status = EFI_OUT_OF_RESOURCES;
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Fill Certificate Database parameters.
 | |
|   //
 | |
|   CACert = (EFI_SIGNATURE_LIST*) Data;
 | |
|   CACert->SignatureListSize   = (UINT32) SigDataSize;
 | |
|   CACert->SignatureHeaderSize = 0;
 | |
|   CACert->SignatureSize = (UINT32) (sizeof(EFI_SIGNATURE_DATA) - 1 + X509DataSize);
 | |
|   CopyGuid (&CACert->SignatureType, &gEfiCertX509Guid);
 | |
| 
 | |
|   CACertData = (EFI_SIGNATURE_DATA*) ((UINT8* ) CACert + sizeof (EFI_SIGNATURE_LIST));
 | |
|   CopyGuid (&CACertData->SignatureOwner, Private->CertGuid);
 | |
|   CopyMem ((UINT8* ) (CACertData->SignatureData), X509Data, X509DataSize);
 | |
| 
 | |
|   //
 | |
|   // Check if the signature database entry already exists. If it does, use the
 | |
|   // EFI_VARIABLE_APPEND_WRITE attribute to append the new signature data to
 | |
|   // the original variable, plus preserve the original variable attributes.
 | |
|   //
 | |
|   Status = gRT->GetVariable(
 | |
|                   VariableName,
 | |
|                   &gEfiTlsCaCertificateGuid,
 | |
|                   &Attr,
 | |
|                   &DataSize,
 | |
|                   NULL
 | |
|                   );
 | |
|   if (Status == EFI_BUFFER_TOO_SMALL) {
 | |
|     Attr |= EFI_VARIABLE_APPEND_WRITE;
 | |
|   } else if (Status == EFI_NOT_FOUND) {
 | |
|     Attr = TLS_AUTH_CONFIG_VAR_BASE_ATTR;
 | |
|   } else {
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   Status = gRT->SetVariable(
 | |
|                   VariableName,
 | |
|                   &gEfiTlsCaCertificateGuid,
 | |
|                   Attr,
 | |
|                   SigDataSize,
 | |
|                   Data
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
| ON_EXIT:
 | |
|   CleanFileContext (Private);
 | |
| 
 | |
|   if (Private->CertGuid != NULL) {
 | |
|     FreePool (Private->CertGuid);
 | |
|     Private->CertGuid = NULL;
 | |
|   }
 | |
| 
 | |
|   if (Data != NULL) {
 | |
|     FreePool (Data);
 | |
|   }
 | |
| 
 | |
|   if (X509Data != NULL) {
 | |
|     FreePool (X509Data);
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Enroll Cert into TlsCaCertificate. The GUID will be Private->CertGuid.
 | |
| 
 | |
|   @param[in] PrivateData     The module's private data.
 | |
|   @param[in] VariableName    Variable name of signature database.
 | |
| 
 | |
|   @retval   EFI_SUCCESS            New Cert enrolled successfully.
 | |
|   @retval   EFI_INVALID_PARAMETER  The parameter is invalid.
 | |
|   @retval   EFI_UNSUPPORTED        The Cert file is unsupported type.
 | |
|   @retval   others                 Fail to enroll Cert data.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EnrollCertDatabase (
 | |
|   IN TLS_AUTH_CONFIG_PRIVATE_DATA  *Private,
 | |
|   IN CHAR16                        *VariableName
 | |
|   )
 | |
| {
 | |
|   UINT16*      FilePostFix;
 | |
|   UINTN        NameLength;
 | |
| 
 | |
|   if ((Private->FileContext->FileName == NULL) || (Private->FileContext->FHandle == NULL) || (Private->CertGuid == NULL)) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Parse the file's postfix.
 | |
|   //
 | |
|   NameLength = StrLen (Private->FileContext->FileName);
 | |
|   if (NameLength <= 4) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
|   FilePostFix = Private->FileContext->FileName + NameLength - 4;
 | |
| 
 | |
|   if (IsDerPemEncodeCertificate (FilePostFix)) {
 | |
|     //
 | |
|     // Supports DER-encoded X509 certificate.
 | |
|     //
 | |
|     return EnrollX509toVariable (Private, VariableName);
 | |
|   }
 | |
| 
 | |
|   return EFI_UNSUPPORTED;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Refresh the global UpdateData structure.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| RefreshUpdateData (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   //
 | |
|   // Free current updated date
 | |
|   //
 | |
|   if (mStartOpCodeHandle != NULL) {
 | |
|     HiiFreeOpCodeHandle (mStartOpCodeHandle);
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Create new OpCode Handle
 | |
|   //
 | |
|   mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
 | |
| 
 | |
|   //
 | |
|   // Create Hii Extend Label OpCode as the start opcode
 | |
|   //
 | |
|   mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
 | |
|                                          mStartOpCodeHandle,
 | |
|                                          &gEfiIfrTianoGuid,
 | |
|                                          NULL,
 | |
|                                          sizeof (EFI_IFR_GUID_LABEL)
 | |
|                                          );
 | |
|   mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Clean up the dynamic opcode at label and form specified by both LabelId.
 | |
| 
 | |
|   @param[in] LabelId         It is both the Form ID and Label ID for opcode deletion.
 | |
|   @param[in] PrivateData     Module private data.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| CleanUpPage (
 | |
|   IN UINT16                           LabelId,
 | |
|   IN TLS_AUTH_CONFIG_PRIVATE_DATA     *PrivateData
 | |
|   )
 | |
| {
 | |
|   RefreshUpdateData ();
 | |
| 
 | |
|   //
 | |
|   // Remove all op-codes from dynamic page
 | |
|   //
 | |
|   mStartLabel->Number = LabelId;
 | |
|   HiiUpdateForm (
 | |
|     PrivateData->RegisteredHandle,
 | |
|     &gTlsAuthConfigGuid,
 | |
|     LabelId,
 | |
|     mStartOpCodeHandle, // Label LabelId
 | |
|     mEndOpCodeHandle    // LABEL_END
 | |
|     );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Update the form base on the selected file.
 | |
| 
 | |
|   @param FilePath   Point to the file path.
 | |
|   @param FormId     The form need to display.
 | |
| 
 | |
|   @retval TRUE   Exit caller function.
 | |
|   @retval FALSE  Not exit caller function.
 | |
| 
 | |
| **/
 | |
| BOOLEAN
 | |
| UpdatePage(
 | |
|   IN  EFI_DEVICE_PATH_PROTOCOL  *FilePath,
 | |
|   IN  EFI_FORM_ID               FormId
 | |
|   )
 | |
| {
 | |
|   CHAR16                *FileName;
 | |
|   EFI_STRING_ID         StringToken;
 | |
| 
 | |
|   FileName = NULL;
 | |
| 
 | |
|   if (FilePath != NULL) {
 | |
|     FileName = ExtractFileNameFromDevicePath(FilePath);
 | |
|   }
 | |
|   if (FileName == NULL) {
 | |
|     //
 | |
|     // FileName = NULL has two case:
 | |
|     // 1. FilePath == NULL, not select file.
 | |
|     // 2. FilePath != NULL, but ExtractFileNameFromDevicePath return NULL not enough memory resource.
 | |
|     // In these two case, no need to update the form, and exit the caller function.
 | |
|     //
 | |
|     return TRUE;
 | |
|   }
 | |
|   StringToken =  HiiSetString (mTlsAuthPrivateData->RegisteredHandle, 0, FileName, NULL);
 | |
| 
 | |
|   mTlsAuthPrivateData->FileContext->FileName = FileName;
 | |
| 
 | |
|   OpenFileByDevicePath (
 | |
|     &FilePath,
 | |
|     &mTlsAuthPrivateData->FileContext->FHandle,
 | |
|     EFI_FILE_MODE_READ,
 | |
|     0
 | |
|     );
 | |
|   //
 | |
|   // Create Subtitle op-code for the display string of the option.
 | |
|   //
 | |
|   RefreshUpdateData ();
 | |
|   mStartLabel->Number = FormId;
 | |
| 
 | |
|   HiiCreateSubTitleOpCode (
 | |
|     mStartOpCodeHandle,
 | |
|     StringToken,
 | |
|     0,
 | |
|     0,
 | |
|     0
 | |
|    );
 | |
| 
 | |
|   HiiUpdateForm (
 | |
|     mTlsAuthPrivateData->RegisteredHandle,
 | |
|     &gTlsAuthConfigGuid,
 | |
|     FormId,
 | |
|     mStartOpCodeHandle, /// Label FormId
 | |
|     mEndOpCodeHandle    /// LABEL_END
 | |
|     );
 | |
| 
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Update the form base on the input file path info.
 | |
| 
 | |
|   @param FilePath    Point to the file path.
 | |
| 
 | |
|   @retval TRUE   Exit caller function.
 | |
|   @retval FALSE  Not exit caller function.
 | |
| **/
 | |
| BOOLEAN
 | |
| EFIAPI
 | |
| UpdateCAFromFile (
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL    *FilePath
 | |
|   )
 | |
| {
 | |
|   return UpdatePage(FilePath, TLS_AUTH_CONFIG_FORMID4_FORM);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Unload the configuration form, this includes: delete all the configuration
 | |
|   entries, uninstall the form callback protocol, and free the resources used.
 | |
| 
 | |
|   @param[in]  Private             Pointer to the driver private data.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The configuration form is unloaded.
 | |
|   @retval Others                  Failed to unload the form.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| TlsAuthConfigFormUnload (
 | |
|   IN TLS_AUTH_CONFIG_PRIVATE_DATA     *Private
 | |
|   )
 | |
| {
 | |
|   if (Private->DriverHandle != NULL) {
 | |
|     //
 | |
|     // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
 | |
|     //
 | |
|     gBS->UninstallMultipleProtocolInterfaces (
 | |
|            Private->DriverHandle,
 | |
|            &gEfiDevicePathProtocolGuid,
 | |
|            &mTlsAuthConfigHiiVendorDevicePath,
 | |
|            &gEfiHiiConfigAccessProtocolGuid,
 | |
|            &Private->ConfigAccess,
 | |
|            NULL
 | |
|            );
 | |
|     Private->DriverHandle = NULL;
 | |
|   }
 | |
| 
 | |
|   if (Private->RegisteredHandle != NULL) {
 | |
|     //
 | |
|     // Remove HII package list
 | |
|     //
 | |
|     HiiRemovePackages (Private->RegisteredHandle);
 | |
|     Private->RegisteredHandle = NULL;
 | |
|   }
 | |
| 
 | |
|   if (Private->CertGuid != NULL) {
 | |
|     FreePool (Private->CertGuid);
 | |
|   }
 | |
| 
 | |
|   if (Private->FileContext != NULL) {
 | |
|     FreePool (Private->FileContext);
 | |
|   }
 | |
| 
 | |
|   FreePool (Private);
 | |
| 
 | |
|   if (mStartOpCodeHandle != NULL) {
 | |
|     HiiFreeOpCodeHandle (mStartOpCodeHandle);
 | |
|   }
 | |
| 
 | |
|   if (mEndOpCodeHandle != NULL) {
 | |
|     HiiFreeOpCodeHandle (mEndOpCodeHandle);
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Initialize the configuration form.
 | |
| 
 | |
|   @param[in]  Private             Pointer to the driver private data.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The configuration form is initialized.
 | |
|   @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| TlsAuthConfigFormInit (
 | |
|   IN TLS_AUTH_CONFIG_PRIVATE_DATA     *Private
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                        Status;
 | |
| 
 | |
|   Private->Signature = TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE;
 | |
| 
 | |
|   Private->ConfigAccess.ExtractConfig = TlsAuthConfigAccessExtractConfig;
 | |
|   Private->ConfigAccess.RouteConfig   = TlsAuthConfigAccessRouteConfig;
 | |
|   Private->ConfigAccess.Callback      = TlsAuthConfigAccessCallback;
 | |
| 
 | |
|   //
 | |
|   // Install Device Path Protocol and Config Access protocol to driver handle.
 | |
|   //
 | |
|   Status = gBS->InstallMultipleProtocolInterfaces (
 | |
|                   &Private->DriverHandle,
 | |
|                   &gEfiDevicePathProtocolGuid,
 | |
|                   &mTlsAuthConfigHiiVendorDevicePath,
 | |
|                   &gEfiHiiConfigAccessProtocolGuid,
 | |
|                   &Private->ConfigAccess,
 | |
|                   NULL
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Publish our HII data.
 | |
|   //
 | |
|   Private->RegisteredHandle = HiiAddPackages (
 | |
|                                 &gTlsAuthConfigGuid,
 | |
|                                 Private->DriverHandle,
 | |
|                                 TlsAuthConfigDxeStrings,
 | |
|                                 TlsAuthConfigVfrBin,
 | |
|                                 NULL
 | |
|                                 );
 | |
|   if (Private->RegisteredHandle == NULL) {
 | |
|     Status = EFI_OUT_OF_RESOURCES;
 | |
|     goto Error;
 | |
|   }
 | |
| 
 | |
|   Private->FileContext = AllocateZeroPool (sizeof (TLS_AUTH_CONFIG_FILE_CONTEXT));
 | |
|   if (Private->FileContext == NULL) {
 | |
|     Status = EFI_OUT_OF_RESOURCES;
 | |
|     goto Error;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Init OpCode Handle and Allocate space for creation of Buffer
 | |
|   //
 | |
|   mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
 | |
|   if (mStartOpCodeHandle == NULL) {
 | |
|     Status = EFI_OUT_OF_RESOURCES;
 | |
|     goto Error;
 | |
|   }
 | |
| 
 | |
|   mEndOpCodeHandle = HiiAllocateOpCodeHandle ();
 | |
|   if (mEndOpCodeHandle == NULL) {
 | |
|     Status = EFI_OUT_OF_RESOURCES;
 | |
|     goto Error;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Create Hii Extend Label OpCode as the start opcode
 | |
|   //
 | |
|   mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
 | |
|                                          mStartOpCodeHandle,
 | |
|                                          &gEfiIfrTianoGuid,
 | |
|                                          NULL,
 | |
|                                          sizeof (EFI_IFR_GUID_LABEL)
 | |
|                                          );
 | |
|   mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
 | |
| 
 | |
|   //
 | |
|   // Create Hii Extend Label OpCode as the end opcode
 | |
|   //
 | |
|   mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
 | |
|                                        mEndOpCodeHandle,
 | |
|                                        &gEfiIfrTianoGuid,
 | |
|                                        NULL,
 | |
|                                        sizeof (EFI_IFR_GUID_LABEL)
 | |
|                                        );
 | |
|   mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
 | |
|   mEndLabel->Number       = LABEL_END;
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| 
 | |
| Error:
 | |
|   TlsAuthConfigFormUnload (Private);
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
| 
 | |
|   This function allows the caller to request the current
 | |
|   configuration for one or more named elements. The resulting
 | |
|   string is in <ConfigAltResp> format. Any and all alternative
 | |
|   configuration strings shall also be appended to the end of the
 | |
|   current configuration string. If they are, they must appear
 | |
|   after the current configuration. They must contain the same
 | |
|   routing (GUID, NAME, PATH) as the current configuration string.
 | |
|   They must have an additional description indicating the type of
 | |
|   alternative configuration the string represents,
 | |
|   "ALTCFG=<StringToken>". That <StringToken> (when
 | |
|   converted from Hex UNICODE to binary) is a reference to a
 | |
|   string in the associated string pack.
 | |
| 
 | |
|   @param This       Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
 | |
| 
 | |
|   @param Request    A null-terminated Unicode string in
 | |
|                     <ConfigRequest> format. Note that this
 | |
|                     includes the routing information as well as
 | |
|                     the configurable name / value pairs. It is
 | |
|                     invalid for this string to be in
 | |
|                     <MultiConfigRequest> format.
 | |
|                     If a NULL is passed in for the Request field,
 | |
|                     all of the settings being abstracted by this function
 | |
|                     will be returned in the Results field.  In addition,
 | |
|                     if a ConfigHdr is passed in with no request elements,
 | |
|                     all of the settings being abstracted for that particular
 | |
|                     ConfigHdr reference will be returned in the Results Field.
 | |
| 
 | |
|   @param Progress   On return, points to a character in the
 | |
|                     Request string. Points to the string's null
 | |
|                     terminator if request was successful. Points
 | |
|                     to the most recent "&" before the first
 | |
|                     failing name / value pair (or the beginning
 | |
|                     of the string if the failure is in the first
 | |
|                     name / value pair) if the request was not
 | |
|                     successful.
 | |
| 
 | |
|   @param Results    A null-terminated Unicode string in
 | |
|                     <MultiConfigAltResp> format which has all values
 | |
|                     filled in for the names in the Request string.
 | |
|                     String to be allocated by the called function.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The Results string is filled with the
 | |
|                                   values corresponding to all requested
 | |
|                                   names.
 | |
| 
 | |
|   @retval EFI_OUT_OF_RESOURCES    Not enough memory to store the
 | |
|                                   parts of the results that must be
 | |
|                                   stored awaiting possible future
 | |
|                                   protocols.
 | |
| 
 | |
|   @retval EFI_NOT_FOUND           Routing data doesn't match any
 | |
|                                   known driver. Progress set to the
 | |
|                                   first character in the routing header.
 | |
|                                   Note: There is no requirement that the
 | |
|                                   driver validate the routing data. It
 | |
|                                   must skip the <ConfigHdr> in order to
 | |
|                                   process the names.
 | |
| 
 | |
|   @retval EFI_INVALID_PARAMETER   Illegal syntax. Progress set
 | |
|                                   to most recent "&" before the
 | |
|                                   error or the beginning of the
 | |
|                                   string.
 | |
| 
 | |
|   @retval EFI_INVALID_PARAMETER   Unknown name. Progress points
 | |
|                                   to the & before the name in
 | |
|                                   question.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| TlsAuthConfigAccessExtractConfig (
 | |
|   IN CONST  EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
 | |
|   IN CONST  EFI_STRING                      Request,
 | |
|   OUT       EFI_STRING                      *Progress,
 | |
|   OUT       EFI_STRING                      *Results
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                        Status;
 | |
|   UINTN                             BufferSize;
 | |
|   UINTN                             Size;
 | |
|   EFI_STRING                        ConfigRequest;
 | |
|   EFI_STRING                        ConfigRequestHdr;
 | |
|   TLS_AUTH_CONFIG_PRIVATE_DATA      *Private;
 | |
|   BOOLEAN                           AllocatedRequest;
 | |
| 
 | |
|   if (Progress == NULL || Results == NULL) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   AllocatedRequest = FALSE;
 | |
|   ConfigRequestHdr = NULL;
 | |
|   ConfigRequest    = NULL;
 | |
|   Size             = 0;
 | |
| 
 | |
|   Private          = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
 | |
| 
 | |
|   BufferSize       = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
 | |
|   ZeroMem (&Private->TlsAuthConfigNvData, BufferSize);
 | |
| 
 | |
|   *Progress        = Request;
 | |
| 
 | |
|   if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) {
 | |
|     return EFI_NOT_FOUND;
 | |
|   }
 | |
| 
 | |
|   ConfigRequest = Request;
 | |
|   if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
 | |
|     //
 | |
|     // Request is set to NULL or OFFSET is NULL, construct full request string.
 | |
|     //
 | |
|     // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
 | |
|     // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
 | |
|     //
 | |
|     ConfigRequestHdr = HiiConstructConfigHdr (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, Private->DriverHandle);
 | |
|     Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
 | |
|     ConfigRequest = AllocateZeroPool (Size);
 | |
|     ASSERT (ConfigRequest != NULL);
 | |
|     AllocatedRequest = TRUE;
 | |
|     UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
 | |
|     FreePool (ConfigRequestHdr);
 | |
|     ConfigRequestHdr = NULL;
 | |
|   }
 | |
| 
 | |
|   Status = gHiiConfigRouting->BlockToConfig (
 | |
|                                 gHiiConfigRouting,
 | |
|                                 ConfigRequest,
 | |
|                                 (UINT8 *) &Private->TlsAuthConfigNvData,
 | |
|                                 BufferSize,
 | |
|                                 Results,
 | |
|                                 Progress
 | |
|                                 );
 | |
| 
 | |
|   //
 | |
|   // Free the allocated config request string.
 | |
|   //
 | |
|   if (AllocatedRequest) {
 | |
|     FreePool (ConfigRequest);
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Set Progress string to the original request string.
 | |
|   //
 | |
|   if (Request == NULL) {
 | |
|     *Progress = NULL;
 | |
|   } else if (StrStr (Request, L"OFFSET") == NULL) {
 | |
|     *Progress = Request + StrLen (Request);
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
| 
 | |
|   This function applies changes in a driver's configuration.
 | |
|   Input is a Configuration, which has the routing data for this
 | |
|   driver followed by name / value configuration pairs. The driver
 | |
|   must apply those pairs to its configurable storage. If the
 | |
|   driver's configuration is stored in a linear block of data
 | |
|   and the driver's name / value pairs are in <BlockConfig>
 | |
|   format, it may use the ConfigToBlock helper function (above) to
 | |
|   simplify the job.
 | |
| 
 | |
|   @param This           Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
 | |
| 
 | |
|   @param Configuration  A null-terminated Unicode string in
 | |
|                         <ConfigString> format.
 | |
| 
 | |
|   @param Progress       A pointer to a string filled in with the
 | |
|                         offset of the most recent '&' before the
 | |
|                         first failing name / value pair (or the
 | |
|                         beginn ing of the string if the failure
 | |
|                         is in the first name / value pair) or
 | |
|                         the terminating NULL if all was
 | |
|                         successful.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The results have been distributed or are
 | |
|                                   awaiting distribution.
 | |
| 
 | |
|   @retval EFI_OUT_OF_RESOURCES    Not enough memory to store the
 | |
|                                   parts of the results that must be
 | |
|                                   stored awaiting possible future
 | |
|                                   protocols.
 | |
| 
 | |
|   @retval EFI_INVALID_PARAMETERS  Passing in a NULL for the
 | |
|                                   Results parameter would result
 | |
|                                   in this type of error.
 | |
| 
 | |
|   @retval EFI_NOT_FOUND           Target for the specified routing data
 | |
|                                   was not found
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| TlsAuthConfigAccessRouteConfig (
 | |
|   IN CONST  EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
 | |
|   IN CONST  EFI_STRING                      Configuration,
 | |
|   OUT       EFI_STRING                      *Progress
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                       Status;
 | |
|   UINTN                            BufferSize;
 | |
|   TLS_AUTH_CONFIG_PRIVATE_DATA     *Private;
 | |
| 
 | |
|   if (Progress == NULL) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
|   *Progress = Configuration;
 | |
| 
 | |
|   if (Configuration == NULL) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Check routing data in <ConfigHdr>.
 | |
|   // Note: there is no name for Name/Value storage, only GUID will be checked
 | |
|   //
 | |
|   if (!HiiIsConfigHdrMatch (Configuration, &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) {
 | |
|     return EFI_NOT_FOUND;
 | |
|   }
 | |
| 
 | |
|   Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
 | |
| 
 | |
|   BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
 | |
|   ZeroMem (&Private->TlsAuthConfigNvData, BufferSize);
 | |
| 
 | |
|   Status = gHiiConfigRouting->ConfigToBlock (
 | |
|                                 gHiiConfigRouting,
 | |
|                                 Configuration,
 | |
|                                 (UINT8 *) &Private->TlsAuthConfigNvData,
 | |
|                                 &BufferSize,
 | |
|                                 Progress
 | |
|                                 );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
| 
 | |
|   This function is called to provide results data to the driver.
 | |
|   This data consists of a unique key that is used to identify
 | |
|   which data is either being passed back or being asked for.
 | |
| 
 | |
|   @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
 | |
|   @param  Action                 Specifies the type of action taken by the browser.
 | |
|   @param  QuestionId             A unique value which is sent to the original
 | |
|                                  exporting driver so that it can identify the type
 | |
|                                  of data to expect. The format of the data tends to
 | |
|                                  vary based on the opcode that generated the callback.
 | |
|   @param  Type                   The type of value for the question.
 | |
|   @param  Value                  A pointer to the data being sent to the original
 | |
|                                  exporting driver.
 | |
|   @param  ActionRequest          On return, points to the action requested by the
 | |
|                                  callback function.
 | |
| 
 | |
|   @retval EFI_SUCCESS            The callback successfully handled the action.
 | |
|   @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the
 | |
|                                  variable and its data.
 | |
|   @retval EFI_DEVICE_ERROR       The variable could not be saved.
 | |
|   @retval EFI_UNSUPPORTED        The specified Action is not supported by the
 | |
|                                  callback.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| TlsAuthConfigAccessCallback (
 | |
|   IN     CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
 | |
|   IN     EFI_BROWSER_ACTION                     Action,
 | |
|   IN     EFI_QUESTION_ID                        QuestionId,
 | |
|   IN     UINT8                                  Type,
 | |
|   IN OUT EFI_IFR_TYPE_VALUE                     *Value,
 | |
|   OUT    EFI_BROWSER_ACTION_REQUEST             *ActionRequest
 | |
|   )
 | |
| {
 | |
|   EFI_INPUT_KEY                   Key;
 | |
|   EFI_STATUS                      Status;
 | |
|   RETURN_STATUS                   RStatus;
 | |
|   TLS_AUTH_CONFIG_PRIVATE_DATA    *Private;
 | |
|   UINTN                           BufferSize;
 | |
|   TLS_AUTH_CONFIG_IFR_NVDATA      *IfrNvData;
 | |
|   UINT16                          LabelId;
 | |
|   EFI_DEVICE_PATH_PROTOCOL        *File;
 | |
| 
 | |
|   Status           = EFI_SUCCESS;
 | |
|   File             = NULL;
 | |
| 
 | |
|   if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
 | |
| 
 | |
|   mTlsAuthPrivateData = Private;
 | |
| 
 | |
|   //
 | |
|   // Retrieve uncommitted data from Browser
 | |
|   //
 | |
|   BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
 | |
|   IfrNvData = AllocateZeroPool (BufferSize);
 | |
|   if (IfrNvData == NULL) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   HiiGetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, BufferSize, (UINT8 *) IfrNvData);
 | |
| 
 | |
|   if ((Action != EFI_BROWSER_ACTION_CHANGED) &&
 | |
|       (Action != EFI_BROWSER_ACTION_CHANGING) && 
 | |
|       (Action != EFI_BROWSER_ACTION_FORM_CLOSE)) {
 | |
|     Status = EFI_UNSUPPORTED;
 | |
|     goto EXIT;
 | |
|   }
 | |
| 
 | |
|   if (Action == EFI_BROWSER_ACTION_CHANGING) {
 | |
|     switch (QuestionId) {
 | |
|     case KEY_TLS_AUTH_CONFIG_CLIENT_CERT:
 | |
|     case KEY_TLS_AUTH_CONFIG_SERVER_CA:
 | |
|       //
 | |
|       // Clear Cert GUID.
 | |
|       //
 | |
|       ZeroMem (IfrNvData->CertGuid, sizeof (IfrNvData->CertGuid));
 | |
|       if (Private->CertGuid == NULL) {
 | |
|         Private->CertGuid = (EFI_GUID *) AllocateZeroPool (sizeof (EFI_GUID));
 | |
|         if (Private->CertGuid == NULL) {
 | |
|           return EFI_OUT_OF_RESOURCES;
 | |
|         }
 | |
|       }
 | |
|       if (QuestionId == KEY_TLS_AUTH_CONFIG_CLIENT_CERT) {
 | |
|         LabelId = TLS_AUTH_CONFIG_FORMID3_FORM;
 | |
|       } else {
 | |
|         LabelId = TLS_AUTH_CONFIG_FORMID4_FORM;
 | |
|       }
 | |
| 
 | |
|       //
 | |
|       // Refresh selected file.
 | |
|       //
 | |
|       CleanUpPage (LabelId, Private);
 | |
|       break;
 | |
|     case KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE:
 | |
|       //
 | |
|       // If the file is already opened, clean the file related resource first. 
 | |
|       //
 | |
|       CleanFileContext (Private);
 | |
|       
 | |
|       ChooseFile( NULL, NULL, UpdateCAFromFile, &File);
 | |
|       break;
 | |
| 
 | |
|     case KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT:
 | |
|       Status = EnrollCertDatabase (Private, EFI_TLS_CA_CERTIFICATE_VARIABLE);
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         CleanFileContext (Private);
 | |
| 
 | |
|         CreatePopUp (
 | |
|           EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
 | |
|           &Key,
 | |
|           L"ERROR: Enroll Cert Failure!",
 | |
|           NULL
 | |
|           );
 | |
|       }
 | |
|       break;
 | |
| 
 | |
|     case KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT:
 | |
|       CleanFileContext (Private);
 | |
| 
 | |
|       if (Private->CertGuid!= NULL) {
 | |
|         FreePool (Private->CertGuid);
 | |
|         Private->CertGuid = NULL;
 | |
|       }
 | |
|       break;
 | |
| 
 | |
|     case KEY_TLS_AUTH_CONFIG_DELETE_CERT:
 | |
|       UpdateDeletePage (
 | |
|         Private,
 | |
|         EFI_TLS_CA_CERTIFICATE_VARIABLE,
 | |
|         &gEfiTlsCaCertificateGuid,
 | |
|         LABEL_CA_DELETE,
 | |
|         TLS_AUTH_CONFIG_FORMID5_FORM,
 | |
|         OPTION_DEL_CA_ESTION_ID
 | |
|         );
 | |
|        break;
 | |
| 
 | |
|     default:
 | |
|       if ((QuestionId >= OPTION_DEL_CA_ESTION_ID) &&
 | |
|                  (QuestionId < (OPTION_DEL_CA_ESTION_ID + OPTION_CONFIG_RANGE)))  {
 | |
|         DeleteCert (
 | |
|           Private,
 | |
|           EFI_TLS_CA_CERTIFICATE_VARIABLE,
 | |
|           &gEfiTlsCaCertificateGuid,
 | |
|           LABEL_CA_DELETE,
 | |
|           TLS_AUTH_CONFIG_FORMID5_FORM,
 | |
|           OPTION_DEL_CA_ESTION_ID,
 | |
|           QuestionId - OPTION_DEL_CA_ESTION_ID
 | |
|           );
 | |
|       }
 | |
|       break;
 | |
|     }
 | |
|   } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
 | |
|     switch (QuestionId) {
 | |
|     case KEY_TLS_AUTH_CONFIG_CERT_GUID:
 | |
|       ASSERT (Private->CertGuid != NULL);
 | |
|       RStatus = StrToGuid (
 | |
|                   IfrNvData->CertGuid,
 | |
|                   Private->CertGuid
 | |
|                   );
 | |
|       if (RETURN_ERROR (RStatus) || (IfrNvData->CertGuid[GUID_STRING_LENGTH] != L'\0')) {
 | |
|         Status = EFI_INVALID_PARAMETER;
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
 | |
|       break;
 | |
|     default:
 | |
|       break;
 | |
|     }
 | |
|   } else if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) {
 | |
|     CleanFileContext (Private);
 | |
|   }
 | |
| 
 | |
| EXIT:
 | |
| 
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
 | |
|     HiiSetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, BufferSize, (UINT8*) IfrNvData, NULL);
 | |
|   }
 | |
| 
 | |
|   FreePool (IfrNvData);
 | |
| 
 | |
|   if (File != NULL){
 | |
|     FreePool(File);
 | |
|     File = NULL;
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| 
 | |
| }
 | |
| 
 |