v2:
* Define one new internal function to clean the file content.
TlsAuthConfigDxe open file by FileExplorerLib. It need to close
file handler and free file related resource in some cases.
* User enrolls Cert by escape the Config page.
* The Cert is not X509 type.
* User chooses another file after he selected a file.
Cc: Zhang Chao B <chao.b.zhang@intel.com>
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
Reviewed-by: Chao Zhang<chao.b.zhang@intel.com>
(cherry picked from commit 8ca4176883)
		
	
		
			
				
	
	
		
			1691 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1691 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;
 | 
						|
 | 
						|
  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 signature database entry has been already existed.
 | 
						|
  // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
 | 
						|
  // new signature data to original variable
 | 
						|
  //
 | 
						|
  Attr = TLS_AUTH_CONFIG_VAR_BASE_ATTR;
 | 
						|
 | 
						|
  Status = gRT->GetVariable(
 | 
						|
                  VariableName,
 | 
						|
                  &gEfiTlsCaCertificateGuid,
 | 
						|
                  NULL,
 | 
						|
                  &DataSize,
 | 
						|
                  NULL
 | 
						|
                  );
 | 
						|
  if (Status == EFI_BUFFER_TOO_SMALL) {
 | 
						|
    Attr |= EFI_VARIABLE_APPEND_WRITE;
 | 
						|
  } else if (Status != EFI_NOT_FOUND) {
 | 
						|
    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;
 | 
						|
 | 
						|
}
 | 
						|
 |