NetworkPkg/TlsAuthConfigDxe: Provide the UI to support TLS auth configuration
authorJiaxin Wu <jiaxin.wu@intel.com>
Wed, 14 Dec 2016 02:54:32 +0000 (10:54 +0800)
committerJiaxin Wu <jiaxin.wu@intel.com>
Thu, 22 Dec 2016 12:33:35 +0000 (20:33 +0800)
This patch provides the UI to support TLS auth configuration.
* EFI_SIGNATURE_LIST format is used for 'TlsCaCertificate'
variable. So, TLS supports multiple certificate configuration.
* The variable attribute is BS with NV, which only target at
preventing runtime phase attack.

Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
Reviewed-by: Ye Ting <ting.ye@intel.com>
12 files changed:
NetworkPkg/Include/Guid/TlsAuthConfigHii.h [new file with mode: 0644]
NetworkPkg/Include/Guid/TlsAuthentication.h [new file with mode: 0644]
NetworkPkg/NetworkPkg.dec
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c [new file with mode: 0644]
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf [new file with mode: 0644]
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni [new file with mode: 0644]
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni [new file with mode: 0644]
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni [new file with mode: 0644]
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c [new file with mode: 0644]
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h [new file with mode: 0644]
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h [new file with mode: 0644]
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr [new file with mode: 0644]

diff --git a/NetworkPkg/Include/Guid/TlsAuthConfigHii.h b/NetworkPkg/Include/Guid/TlsAuthConfigHii.h
new file mode 100644 (file)
index 0000000..9d21426
--- /dev/null
@@ -0,0 +1,25 @@
+/** @file
+  GUIDs used as HII FormSet and HII Package list GUID in TlsAuthConfigDxe driver. 
+  
+Copyright (c) 2016, 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 that 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.
+
+**/
+
+#ifndef __TLS_AUTH_CONFIG_HII_GUID_H__
+#define __TLS_AUTH_CONFIG_HII_GUID_H__
+
+#define TLS_AUTH_CONFIG_GUID \
+  { \
+    0xb0eae4f8, 0x9a04, 0x4c6d, { 0xa7, 0x48, 0x79, 0x3d, 0xaa, 0xf, 0x65, 0xdf } \
+  }
+
+extern EFI_GUID gTlsAuthConfigGuid;
+
+#endif
diff --git a/NetworkPkg/Include/Guid/TlsAuthentication.h b/NetworkPkg/Include/Guid/TlsAuthentication.h
new file mode 100644 (file)
index 0000000..2e800dc
--- /dev/null
@@ -0,0 +1,29 @@
+/** @file
+  This file defines TlsCaCertificate variable.
+  
+Copyright (c) 2016, 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 that 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.
+
+**/
+
+#ifndef __TLS_AUTHENTICATION_H__
+#define __TLS_AUTHENTICATION_H__
+
+// Private variable for CA Certificate configuration
+//
+#define EFI_TLS_CA_CERTIFICATE_GUID \
+  { \
+    0xfd2340D0, 0x3dab, 0x4349, { 0xa6, 0xc7, 0x3b, 0x4f, 0x12, 0xb4, 0x8e, 0xae } \
+  }
+
+#define EFI_TLS_CA_CERTIFICATE_VARIABLE       L"TlsCaCertificate"
+
+extern EFI_GUID gEfiTlsCaCertificateGuid;
+
+#endif
index 268188a..24d45f4 100644 (file)
   # Include/Guid/HttpBootConfigHii.h\r
   gHttpBootConfigGuid           = { 0x4d20583a, 0x7765, 0x4e7a, { 0x8a, 0x67, 0xdc, 0xde, 0x74, 0xee, 0x3e, 0xc5 }}\r
 \r
+  # Include/Guid/TlsAuthConfigHii.h\r
+  gTlsAuthConfigGuid            = { 0xb0eae4f8, 0x9a04, 0x4c6d, { 0xa7, 0x48, 0x79, 0x3d, 0xaa, 0xf, 0x65, 0xdf }}\r
+  \r
+  # Include/Guid/TlsAuthentication.h\r
+  gEfiTlsCaCertificateGuid      = { 0xfd2340D0, 0x3dab, 0x4349, { 0xa6, 0xc7, 0x3b, 0x4f, 0x12, 0xb4, 0x8e, 0xae }}\r
+  \r
+\r
 [PcdsFeatureFlag]\r
   ## Indicates if the IPsec IKEv2 Certificate Authentication feature is enabled or not.<BR><BR>\r
   #   TRUE  - Certificate Authentication feature is enabled.<BR>\r
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c
new file mode 100644 (file)
index 0000000..647bc2f
--- /dev/null
@@ -0,0 +1,135 @@
+/** @file
+  The DriverEntryPoint for TlsAuthConfigDxe driver.
+
+  Copyright (c) 2016, 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"
+
+/**
+  Unloads an image.
+
+  @param  ImageHandle           Handle that identifies the image to be unloaded.
+
+  @retval EFI_SUCCESS           The image has been unloaded.
+  @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS 
+EFIAPI
+TlsAuthConfigDxeUnload (
+  IN EFI_HANDLE  ImageHandle
+  )
+{
+  EFI_STATUS                     Status;
+  TLS_AUTH_CONFIG_PRIVATE_DATA   *PrivateData;
+
+  Status = gBS->HandleProtocol (
+                  ImageHandle,
+                  &gEfiCallerIdGuid,
+                  (VOID **) &PrivateData
+                  );  
+  if (EFI_ERROR (Status)) {
+    return Status;  
+  }
+  
+  ASSERT (PrivateData->Signature == TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE);
+
+  gBS->UninstallMultipleProtocolInterfaces (
+         &ImageHandle,
+         &gEfiCallerIdGuid,
+         PrivateData,
+         NULL
+         );
+  
+  TlsAuthConfigFormUnload (PrivateData);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This is the declaration of an EFI image entry point. This entry point is
+  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+  both device drivers and bus drivers.
+
+  @param  ImageHandle           The firmware allocated handle for the UEFI image.
+  @param  SystemTable           A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval Others                An unexpected error occurred.
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigDxeDriverEntryPoint (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  TLS_AUTH_CONFIG_PRIVATE_DATA   *PrivateData;
+
+  PrivateData = NULL;
+  
+  //
+  // If already started, return.
+  //
+  Status = gBS->OpenProtocol (
+                  ImageHandle,
+                  &gEfiCallerIdGuid,
+                  NULL,
+                  ImageHandle,
+                  ImageHandle,
+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+                  );
+  if (!EFI_ERROR (Status)) {
+    return EFI_ALREADY_STARTED;
+  }
+
+  //
+  // Initialize the private data structure.
+  //
+  PrivateData = AllocateZeroPool (sizeof (TLS_AUTH_CONFIG_PRIVATE_DATA));
+  if (PrivateData == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Initialize the HII configuration form.
+  //
+  Status = TlsAuthConfigFormInit (PrivateData);
+  if (EFI_ERROR (Status)) {
+    goto ON_ERROR;
+  }
+
+  //
+  // Install private GUID.
+  //    
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gEfiCallerIdGuid,
+                  PrivateData,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    goto ON_ERROR;
+  }
+  
+  return EFI_SUCCESS;
+
+ON_ERROR:
+  TlsAuthConfigFormUnload (PrivateData);
+  FreePool (PrivateData);
+
+  return Status;
+}
+
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
new file mode 100644 (file)
index 0000000..19f095e
--- /dev/null
@@ -0,0 +1,73 @@
+## @file
+#  Provides the capability to configure Tls Authentication in a setup browser
+#  By this module, user may change the content of TlsCaCertificate.
+#
+# Copyright (c) 2016, 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.
+#
+##
+
+[Defines]
+  INF_VERSION               = 0x00010005
+  BASE_NAME                 = TlsAuthConfigDxe
+  MODULE_UNI_FILE           = TlsAuthConfigDxe.uni
+  FILE_GUID                 = 7ca1024f-eb17-11e5-9dba-28d2447c4829
+  MODULE_TYPE               = DXE_DRIVER
+  VERSION_STRING            = 1.0
+  ENTRY_POINT               = TlsAuthConfigDxeDriverEntryPoint
+  UNLOAD_IMAGE              = TlsAuthConfigDxeUnload
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+  
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  NetworkPkg/NetworkPkg.dec
+
+[Sources]
+  TlsAuthConfigImpl.c
+  TlsAuthConfigImpl.h
+  TlsAuthConfigNvData.h
+  TlsAuthConfigDxe.c
+  TlsAuthConfigDxeStrings.uni
+  TlsAuthConfigVfr.vfr
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  UefiLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  UefiDriverEntryPoint
+  DebugLib
+  HiiLib
+  DevicePathLib
+  UefiHiiServicesLib
+  FileExplorerLib
+  PrintLib
+  
+[Protocols]
+  gEfiDevicePathProtocolGuid                    ## PRODUCES
+  gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
+  gEfiSimpleFileSystemProtocolGuid              ## SOMETIMES_CONSUMES
+
+[Guids]
+  gTlsAuthConfigGuid                            ## PRODUCES  ## GUID
+  gEfiCertX509Guid                              ## CONSUMES  ## GUID  # Indicate the cert type
+  gEfiIfrTianoGuid                              ## CONSUMES  ## HII
+  gEfiTlsCaCertificateGuid                      ## PRODUCES  ## GUID
+
+[Depex]
+  gEfiHiiConfigRoutingProtocolGuid  AND
+  gEfiHiiDatabaseProtocolGuid
+  
+[UserExtensions.TianoCore."ExtraFiles"]
+  TlsAuthConfigDxeExtra.uni
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni
new file mode 100644 (file)
index 0000000..f99a14f
--- /dev/null
@@ -0,0 +1,21 @@
+// /** @file
+// Provides the capability to configure Tls Authentication in a setup browser
+//
+// By this module, user may change the content of TlsCaCertificate.
+//
+// Copyright (c) 2016, 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.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "Provides the capability to configure Tls Authentication in a setup browser"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "By this module, user may change the content of TlsCaCertificate."
+
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni
new file mode 100644 (file)
index 0000000..ee4c49f
--- /dev/null
@@ -0,0 +1,19 @@
+// /** @file
+// TlsAuthConfigDxe Localized Strings and Content
+//
+// Copyright (c) 2016, 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.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME 
+#language en-US 
+"TLS Auth Config DXE"
+
+
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni
new file mode 100644 (file)
index 0000000..a8f7e43
--- /dev/null
@@ -0,0 +1,39 @@
+/** @file
+  String definitions for Tls Authentication Configuration form.
+
+Copyright (c) 2016, 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.
+
+**/
+
+#langdef en-US "English"
+
+#string STR_TLS_AUTH_CONFIG_TITLE                    #language en-US "Tls Auth Configuration"
+#string STR_TLS_AUTH_CONFIG_HELP                     #language en-US "Press <Enter> to select Tls Auth Configuration."
+
+#string STR_TLS_AUTH_CONFIG_SERVER_CA                   #language en-US "Server CA Configuration"
+#string STR_TLS_AUTH_CONFIG_SERVER_CA_HELP              #language en-US "Press <Enter> to configure Server CA."
+#string STR_TLS_AUTH_CONFIG_CLIENT_CERT                 #language en-US "Client Cert Configuration"
+#string STR_TLS_AUTH_CONFIG_CLIENT_CERT_HELP            #language en-US "Client cert configuration is unsupported currently."
+
+#string STR_TLS_AUTH_CONFIG_ENROLL_CERT              #language en-US "Enroll Cert"    
+#string STR_TLS_AUTH_CONFIG_ENROLL_CERT_HELP         #language en-US "Press <Enter> to enroll cert."
+#string STR_TLS_AUTH_CONFIG_DELETE_CERT              #language en-US "Delete Cert"    
+#string STR_TLS_AUTH_CONFIG_DELETE_CERT_HELP         #language en-US "Press <Enter> to delete cert."
+
+#string STR_TLS_AUTH_CONFIG_ADD_CERT_FILE            #language en-US "Enroll Cert Using File"
+
+#string STR_TLS_AUTH_CONFIG_CERT_GUID                #language en-US "Cert GUID"
+#string STR_TLS_AUTH_CONFIG_CERT_GUID_HELP           #language en-US "Input digit character in 11111111-2222-3333-4444-1234567890ab format."
+#string STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT            #language en-US "Commit Changes and Exit"
+#string STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT         #language en-US "Discard Changes and Exit"
+
+#string STR_CERT_TYPE_PCKS_GUID                      #language en-US "GUID for CERT"
+
+#string STR_NULL                                     #language en-US ""
\ No newline at end of file
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c
new file mode 100644 (file)
index 0000000..e81e961
--- /dev/null
@@ -0,0 +1,1824 @@
+/** @file
+  The Miscellaneous Routines for TlsAuthConfigDxe driver.
+
+Copyright (c) 2016, 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
+           );
+}
+
+/**
+  Convert a String to Guid Value.
+
+  @param[in]   Str        Specifies the String to be converted.
+  @param[in]   StrLen     Number of Unicode Characters of String (exclusive \0)
+  @param[out]  Guid       Return the result Guid value.
+
+  @retval    EFI_SUCCESS           The operation is finished successfully.
+  @retval    EFI_NOT_FOUND         Invalid string.
+
+**/
+EFI_STATUS
+StringToGuid (
+  IN   CHAR16           *Str, 
+  IN   UINTN            StrLen, 
+  OUT  EFI_GUID         *Guid
+  )
+{
+  CHAR16             *PtrBuffer;
+  CHAR16             *PtrPosition;
+  UINT16             *Buffer;
+  UINTN              Data;
+  UINTN              Index;
+  UINT16             Digits[3];
+
+  Buffer = (CHAR16 *) AllocateZeroPool (sizeof (CHAR16) * (StrLen + 1));
+  if (Buffer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  StrCpyS (Buffer, (StrLen + 1), Str);
+
+  //
+  // Data1
+  //
+  PtrBuffer       = Buffer;
+  PtrPosition     = PtrBuffer; 
+  while (*PtrBuffer != L'\0') {
+    if (*PtrBuffer == L'-') {
+      break;
+    }
+    PtrBuffer++;
+  }
+  if (*PtrBuffer == L'\0') {
+    FreePool (Buffer);
+    return EFI_NOT_FOUND;
+  }
+
+  *PtrBuffer      = L'\0';
+  Data            = StrHexToUintn (PtrPosition);
+  Guid->Data1     = (UINT32)Data;
+
+  //
+  // Data2
+  //
+  PtrBuffer++;
+  PtrPosition     = PtrBuffer;
+  while (*PtrBuffer != L'\0') {
+    if (*PtrBuffer == L'-') {
+      break;
+    }
+    PtrBuffer++;
+  }
+  if (*PtrBuffer == L'\0') {
+    FreePool (Buffer);
+    return EFI_NOT_FOUND;
+  }
+  *PtrBuffer      = L'\0';
+  Data            = StrHexToUintn (PtrPosition);
+  Guid->Data2     = (UINT16)Data;
+
+  //
+  // Data3
+  //
+  PtrBuffer++;
+  PtrPosition     = PtrBuffer;
+  while (*PtrBuffer != L'\0') {
+    if (*PtrBuffer == L'-') {
+      break;
+    }
+    PtrBuffer++;
+  }
+  if (*PtrBuffer == L'\0') {
+    FreePool (Buffer);
+    return EFI_NOT_FOUND;
+  }
+  *PtrBuffer      = L'\0';
+  Data            = StrHexToUintn (PtrPosition);
+  Guid->Data3     = (UINT16)Data;
+
+  //
+  // Data4[0..1]
+  //
+  for ( Index = 0 ; Index < 2 ; Index++) {
+    PtrBuffer++;
+    if ((*PtrBuffer == L'\0') || ( *(PtrBuffer + 1) == L'\0')) {
+      FreePool (Buffer);
+      return EFI_NOT_FOUND;
+    }
+    Digits[0]     = *PtrBuffer;
+    PtrBuffer++;
+    Digits[1]     = *PtrBuffer;
+    Digits[2]     = L'\0';
+    Data          = StrHexToUintn (Digits);
+    Guid->Data4[Index] = (UINT8)Data;
+  }
+
+  //
+  // skip the '-'
+  //
+  PtrBuffer++;
+  if ((*PtrBuffer != L'-' ) || ( *PtrBuffer == L'\0')) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Data4[2..7]
+  //
+  for ( ; Index < 8; Index++) {
+    PtrBuffer++;
+    if ((*PtrBuffer == L'\0') || ( *(PtrBuffer + 1) == L'\0')) {
+      FreePool (Buffer);
+      return EFI_NOT_FOUND;
+    }
+    Digits[0]     = *PtrBuffer;
+    PtrBuffer++;
+    Digits[1]     = *PtrBuffer;
+    Digits[2]     = L'\0';
+    Data          = StrHexToUintn (Digits);
+    Guid->Data4[Index] = (UINT8)Data;
+  }
+
+  FreePool (Buffer);
+  
+  return EFI_SUCCESS;
+}
+
+
+/**
+  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]    PrivateData         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
+           );
+}
+
+
+/**
+  Close an open file handle.
+
+  @param[in] FileHandle           The file handle to close.
+  
+**/
+VOID
+CloseFile (
+  IN EFI_FILE_HANDLE   FileHandle
+  )
+{
+  if (FileHandle != NULL) {
+    FileHandle->Close (FileHandle);  
+  }
+}
+
+/**
+  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:
+
+  CloseFile (Private->FileContext->FHandle);
+  if (Private->FileContext->FileName != NULL) {
+    FreePool(Private->FileContext->FileName);
+    Private->FileContext->FileName = NULL;
+  }
+
+  Private->FileContext->FHandle = NULL;
+
+  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
+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;
+  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)) {
+    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 if (QuestionId == KEY_TLS_AUTH_CONFIG_SERVER_CA) {
+        LabelId = TLS_AUTH_CONFIG_FORMID4_FORM;
+      }
+
+      //
+      // Refresh selected file.
+      //
+      CleanUpPage (LabelId, Private);
+      break;
+    case KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE:
+      ChooseFile( NULL, NULL, (CHOOSE_HANDLER) UpdateCAFromFile, &File);
+      break;
+
+    case KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT:
+      Status = EnrollCertDatabase (Private, EFI_TLS_CA_CERTIFICATE_VARIABLE);
+      if (EFI_ERROR (Status)) {
+        CreatePopUp (
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+          &Key,
+          L"ERROR: Enroll Cert Failure!",
+          NULL
+          );
+      }
+      break;
+
+    case KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT:
+      if (Private->FileContext->FHandle != NULL) {
+        CloseFile (Private->FileContext->FHandle);
+        Private->FileContext->FHandle = NULL;
+        if (Private->FileContext->FileName!= NULL){
+          FreePool(Private->FileContext->FileName);
+          Private->FileContext->FileName = NULL;
+        }
+      }
+
+      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);
+      Status = StringToGuid (
+                 IfrNvData->CertGuid,
+                 StrLen (IfrNvData->CertGuid),
+                 Private->CertGuid
+                 );
+      if (EFI_ERROR (Status)) {
+        break;
+      }
+
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
+      break;
+    default:
+      break;
+    }
+  }
+  
+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;
+
+}
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h
new file mode 100644 (file)
index 0000000..398f7b6
--- /dev/null
@@ -0,0 +1,282 @@
+/** @file
+  Header file of Miscellaneous Routines for TlsAuthConfigDxe driver.
+
+Copyright (c) 2016, 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.
+
+**/
+
+#ifndef __TLS_AUTH_CONFIG_IMPL_H__
+#define __TLS_AUTH_CONFIG_IMPL_H__
+
+#include <Uefi.h>
+
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/SimpleFileSystem.h>
+
+//
+// Libraries
+//
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/UefiHiiServicesLib.h>
+#include <Library/FileExplorerLib.h>
+#include <Library/PrintLib.h>
+
+#include <Guid/MdeModuleHii.h>
+#include <Guid/ImageAuthentication.h>
+#include <Guid/TlsAuthentication.h>
+
+
+//
+// Include files with function prototypes
+//
+#include "TlsAuthConfigNvData.h"
+
+extern   UINT8       TlsAuthConfigDxeStrings[];
+extern   UINT8       TlsAuthConfigVfrBin[];
+
+#define TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE    SIGNATURE_32 ('T', 'A', 'C', 'D')
+#define TLS_AUTH_CONFIG_PRIVATE_FROM_THIS(a)      CR (a, TLS_AUTH_CONFIG_PRIVATE_DATA, ConfigAccess, TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE)
+
+#define TLS_AUTH_CONFIG_VAR_BASE_ATTR  (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS)
+
+typedef struct _TLS_AUTH_CONFIG_PRIVATE_DATA      TLS_AUTH_CONFIG_PRIVATE_DATA;
+typedef struct _TLS_AUTH_CONFIG_FILE_CONTEXT      TLS_AUTH_CONFIG_FILE_CONTEXT;
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+  VENDOR_DEVICE_PATH                VendorDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL          End;
+} HII_VENDOR_DEVICE_PATH;
+
+struct _TLS_AUTH_CONFIG_FILE_CONTEXT {
+  EFI_FILE_HANDLE                   FHandle;
+  UINT16                            *FileName;
+};
+
+struct _TLS_AUTH_CONFIG_PRIVATE_DATA {
+  UINTN                             Signature;
+
+  EFI_HANDLE                        DriverHandle;
+  EFI_HII_HANDLE                    RegisteredHandle;
+  EFI_HII_CONFIG_ACCESS_PROTOCOL    ConfigAccess;
+  TLS_AUTH_CONFIG_IFR_NVDATA        TlsAuthConfigNvData;
+
+  TLS_AUTH_CONFIG_FILE_CONTEXT      *FileContext;
+
+  EFI_GUID                          *CertGuid;
+};
+
+/**
+  Unload the configuration form, this includes: delete all the configuration
+  entries, uninstall the form callback protocol, and free the resources used.
+  The form will only be unload completely when both IP4 and IP6 stack are stopped.
+
+  @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
+  );
+
+/**
+  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
+  );
+
+/**
+   
+  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
+  );
+
+/**
+   
+  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
+  );  
+
+/**
+   
+  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
+  );
+
+#endif
+
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h
new file mode 100644 (file)
index 0000000..f453201
--- /dev/null
@@ -0,0 +1,49 @@
+/** @file
+  Header file for NV data structure definition.
+
+Copyright (c) 2016, 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.
+
+**/
+
+#ifndef __TLS_AUTH_CONFIG_NV_DATA_H__
+#define __TLS_AUTH_CONFIG_NV_DATA_H__
+
+#include <Guid/TlsAuthConfigHii.h>
+
+#define TLS_AUTH_CONFIG_GUID_SIZE                 36
+#define TLS_AUTH_CONFIG_GUID_STORAGE_SIZE         37
+
+#define TLS_AUTH_CONFIG_FORMID1_FORM              1
+#define TLS_AUTH_CONFIG_FORMID2_FORM              2
+#define TLS_AUTH_CONFIG_FORMID3_FORM              3
+#define TLS_AUTH_CONFIG_FORMID4_FORM              4
+#define TLS_AUTH_CONFIG_FORMID5_FORM              5
+
+
+#define KEY_TLS_AUTH_CONFIG_SERVER_CA                  0x1000
+#define KEY_TLS_AUTH_CONFIG_CLIENT_CERT                0x1001
+#define KEY_TLS_AUTH_CONFIG_ENROLL_CERT                0x1002
+#define KEY_TLS_AUTH_CONFIG_DELETE_CERT                0x1003
+#define KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE      0x1004
+#define KEY_TLS_AUTH_CONFIG_CERT_GUID                  0x1005
+#define KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT        0x1006
+#define KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT     0x1007
+
+#define OPTION_DEL_CA_ESTION_ID                        0x2000
+#define OPTION_CONFIG_RANGE                            0x1000
+
+#define LABEL_CA_DELETE                                0x1101
+#define LABEL_END                                      0xffff
+
+typedef struct {
+  CHAR16    CertGuid[TLS_AUTH_CONFIG_GUID_STORAGE_SIZE];
+} TLS_AUTH_CONFIG_IFR_NVDATA;
+
+#endif
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr
new file mode 100644 (file)
index 0000000..fb130d9
--- /dev/null
@@ -0,0 +1,152 @@
+/** @file
+  VFR file used by TlsAuthConfigDxe driver.
+
+  Copyright (c) 2016, 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 "TlsAuthConfigNvData.h"
+
+formset
+  guid   = TLS_AUTH_CONFIG_GUID,
+  title  = STRING_TOKEN(STR_TLS_AUTH_CONFIG_TITLE),
+  help   = STRING_TOKEN(STR_TLS_AUTH_CONFIG_HELP),
+
+  varstore TLS_AUTH_CONFIG_IFR_NVDATA,
+    name = TLS_AUTH_CONFIG_IFR_NVDATA,
+    guid = TLS_AUTH_CONFIG_GUID;
+
+  //
+  // ##1 Form1: Main form for Tls Auth configration
+  //
+  form formid = TLS_AUTH_CONFIG_FORMID1_FORM,
+    title  = STRING_TOKEN(STR_TLS_AUTH_CONFIG_TITLE);
+
+    subtitle text = STRING_TOKEN(STR_NULL);
+    
+    //
+    // Display Server CA configration
+    //
+    goto TLS_AUTH_CONFIG_FORMID2_FORM,
+         prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA),
+         help   = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA_HELP),
+         flags  = INTERACTIVE,
+         key    = KEY_TLS_AUTH_CONFIG_SERVER_CA;
+
+    subtitle text = STRING_TOKEN(STR_NULL);
+
+    //
+    // Display Client cert configration
+    //
+    grayoutif TRUE; /// Current unsupported.
+    goto TLS_AUTH_CONFIG_FORMID3_FORM,
+         prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT),
+         help   = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT_HELP),
+         flags  = INTERACTIVE,
+         key    = KEY_TLS_AUTH_CONFIG_CLIENT_CERT;
+    endif;
+  endform; 
+
+  //
+  // ##2 Form2: CA configuration
+  //
+  form formid = TLS_AUTH_CONFIG_FORMID2_FORM,
+    title  = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA);
+
+    subtitle text = STRING_TOKEN(STR_NULL);
+
+    goto TLS_AUTH_CONFIG_FORMID4_FORM,
+         prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT),
+         help   = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT_HELP),
+         flags  = INTERACTIVE,
+         key    = KEY_TLS_AUTH_CONFIG_ENROLL_CERT;
+
+    subtitle text = STRING_TOKEN(STR_NULL);
+
+    goto TLS_AUTH_CONFIG_FORMID5_FORM,
+         prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT),
+         help   = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT_HELP),
+         flags  = INTERACTIVE,
+         key    = KEY_TLS_AUTH_CONFIG_DELETE_CERT;
+  endform;
+
+  //
+  // ##3 Form3 : Client cert configuration
+  //
+  form formid = TLS_AUTH_CONFIG_FORMID3_FORM,
+    title  = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT);
+    
+    subtitle text = STRING_TOKEN(STR_NULL);
+
+  //
+  // TODO...
+  //
+  endform;
+
+  //
+  // ##4 Form4: Enroll cert for CA
+  //
+  form formid = TLS_AUTH_CONFIG_FORMID4_FORM,
+    title  = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT);
+    
+    subtitle text = STRING_TOKEN(STR_NULL);
+
+    goto TLS_AUTH_CONFIG_FORMID4_FORM,
+         prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ADD_CERT_FILE),
+         help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ADD_CERT_FILE),
+         flags = INTERACTIVE,
+         key = KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE;
+
+    subtitle text = STRING_TOKEN(STR_NULL);
+    label TLS_AUTH_CONFIG_FORMID4_FORM;
+    label LABEL_END;
+    subtitle text = STRING_TOKEN(STR_NULL);
+
+    string  varid   = TLS_AUTH_CONFIG_IFR_NVDATA.CertGuid,
+            prompt  = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CERT_GUID),
+            help    = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CERT_GUID_HELP),
+            flags   = INTERACTIVE,
+            key     = KEY_TLS_AUTH_CONFIG_CERT_GUID,
+            minsize = TLS_AUTH_CONFIG_GUID_SIZE,
+            maxsize = TLS_AUTH_CONFIG_GUID_SIZE,
+    endstring;
+
+    subtitle text = STRING_TOKEN(STR_NULL);
+    subtitle text = STRING_TOKEN(STR_NULL);
+
+    goto TLS_AUTH_CONFIG_FORMID1_FORM,
+         prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT),
+         help   = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT),
+         flags  = INTERACTIVE,
+         key    = KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT;
+
+    goto TLS_AUTH_CONFIG_FORMID1_FORM,
+         prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT),
+         help   = STRING_TOKEN(STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT),
+         flags  = INTERACTIVE,
+         key    = KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT;
+         
+  endform;
+
+  //
+  // ##5 Form5: Delete cert for CA
+  //
+  form formid = TLS_AUTH_CONFIG_FORMID5_FORM,
+    title  = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT);
+
+    label LABEL_CA_DELETE;
+    label LABEL_END;
+    
+    subtitle text = STRING_TOKEN(STR_NULL);
+
+  endform;
+  
+endformset;