public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Wu, Jiaxin" <jiaxin.wu@intel.com>
To: "Ye, Ting" <ting.ye@intel.com>,
	"Fu, Siyuan" <siyuan.fu@intel.com>,
	"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Cc: "Zhang, Lubo" <lubo.zhang@intel.com>,
	"Long, Qin" <qin.long@intel.com>,
	Thomas Palmer <thomas.palmer@hpe.com>
Subject: Re: [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to support TLS auth configuration
Date: Thu, 22 Dec 2016 03:13:05 +0000	[thread overview]
Message-ID: <895558F6EA4E3B41AC93A00D163B72741628DE02@SHSMSX103.ccr.corp.intel.com> (raw)
In-Reply-To: <BC0C045B0E2A584CA4575E779FA2C12A1A8A1573@SHSMSX103.ccr.corp.intel.com>

Thanks Ting. The standardization is in the plan. Before finished, I will keep the existing APIs.

As the return value of GuidToString, you are right, it should be "Size" instead of "Size-1".  I will correct it before commit the patch.

Thanks,
Jiaxin

> -----Original Message-----
> From: Ye, Ting
> Sent: Thursday, December 22, 2016 10:52 AM
> To: Fu, Siyuan <siyuan.fu@intel.com>; Wu, Jiaxin <jiaxin.wu@intel.com>;
> edk2-devel@lists.01.org
> Cc: Zhang, Lubo <lubo.zhang@intel.com>; Long, Qin <qin.long@intel.com>;
> Thomas Palmer <thomas.palmer@hpe.com>
> Subject: RE: [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to
> support TLS auth configuration
> 
> I agree. Adding new StringToGuid and GuidToString to common library seems
> a good idea if we don't have existing APIs.
> 
> In GuidToString, the comment indicates that SPrint will NULL terminate the
> string, so use Size -1 to skip the NULL. However, I see UnicodeSPrint in
> MdePkg returns the number of Unicode characters in the produced output
> buffer, not including the Null-terminator.
> It looks inconsistent to me. Please check that.
> 
> Others are good to me.
> Reviewed-by: Ye Ting <ting.ye@intel.com>
> 
> Best Regards,
> Ting
> 
> 
> -----Original Message-----
> From: Fu, Siyuan
> Sent: Thursday, December 15, 2016 10:22 AM
> To: Wu, Jiaxin <jiaxin.wu@intel.com>; edk2-devel@lists.01.org
> Cc: Ye, Ting <ting.ye@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>;
> Long, Qin <qin.long@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>
> Subject: RE: [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to
> support TLS auth configuration
> 
> Hi, Jiaxin
> 
> PrintLib support "%g" to print a GUID so you don't need to use "%08x-%04x-
> %04x-%02x%02x-%02x%02x%02x%02x%02x%02x" in GuidToString().
> Beside of that, I do see a lot of drivers has similar internal function
> StringToGuid() or StrToGuid(), do we have a common library interface for this?
> if not I think it may worth to create one.
> 
> Other parts are good with me.
> Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
> 
> 
> Best Regards
> Siyuan
> 
> -----Original Message-----
> From: Wu, Jiaxin
> Sent: 2016年12月14日 15:34
> To: edk2-devel@lists.01.org
> Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang,
> Lubo <lubo.zhang@intel.com>; Long, Qin <qin.long@intel.com>; Thomas
> Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
> Subject: [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to
> support TLS auth configuration
> 
> 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>
> ---
>  NetworkPkg/Include/Guid/TlsAuthConfigHii.h         |   25 +
>  NetworkPkg/Include/Guid/TlsAuthentication.h        |   29 +
>  NetworkPkg/NetworkPkg.dec                          |    7 +
>  NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c     |  135 ++
>  NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf   |   73 +
>  NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni   |   21 +
>  .../TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni     |   19 +
>  .../TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni   |   39 +
>  NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c    | 1841
> ++++++++++++++++++++
>  NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h    |  282 +++
>  NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h  |   49 +
>  NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr   |  152 ++
>  12 files changed, 2672 insertions(+)
>  create mode 100644 NetworkPkg/Include/Guid/TlsAuthConfigHii.h
>  create mode 100644 NetworkPkg/Include/Guid/TlsAuthentication.h
>  create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c
>  create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
>  create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni
>  create mode 100644
> NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni
>  create mode 100644
> NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni
>  create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c
>  create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h
>  create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h
>  create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr
> 
> diff --git a/NetworkPkg/Include/Guid/TlsAuthConfigHii.h
> b/NetworkPkg/Include/Guid/TlsAuthConfigHii.h
> new file mode 100644
> index 0000000..9d21426
> --- /dev/null
> +++ b/NetworkPkg/Include/Guid/TlsAuthConfigHii.h
> @@ -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
> index 0000000..2e800dc
> --- /dev/null
> +++ b/NetworkPkg/Include/Guid/TlsAuthentication.h
> @@ -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
> diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec
> index 268188a..24d45f4 100644
> --- a/NetworkPkg/NetworkPkg.dec
> +++ b/NetworkPkg/NetworkPkg.dec
> @@ -38,10 +38,17 @@
>    gIScsiConfigGuid              = { 0x4b47d616, 0xa8d6, 0x4552, { 0x9d, 0x44, 0xcc,
> 0xad, 0x2e, 0xf, 0x4c, 0xf9}}
> 
>    # Include/Guid/HttpBootConfigHii.h
>    gHttpBootConfigGuid           = { 0x4d20583a, 0x7765, 0x4e7a, { 0x8a, 0x67,
> 0xdc, 0xde, 0x74, 0xee, 0x3e, 0xc5 }}
> 
> +  # Include/Guid/TlsAuthConfigHii.h
> +  gTlsAuthConfigGuid            = { 0xb0eae4f8, 0x9a04, 0x4c6d, { 0xa7, 0x48,
> 0x79, 0x3d, 0xaa, 0xf, 0x65, 0xdf }}
> +
> +  # Include/Guid/TlsAuthentication.h
> +  gEfiTlsCaCertificateGuid      = { 0xfd2340D0, 0x3dab, 0x4349, { 0xa6, 0xc7,
> 0x3b, 0x4f, 0x12, 0xb4, 0x8e, 0xae }}
> +
> +
>  [PcdsFeatureFlag]
>    ## Indicates if the IPsec IKEv2 Certificate Authentication feature is enabled
> or not.<BR><BR>
>    #   TRUE  - Certificate Authentication feature is enabled.<BR>
>    #   FALSE - Does not support Certificate Authentication.<BR>
>    # @Prompt Enable IPsec IKEv2 Certificate Authentication.
> diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c
> b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c
> new file mode 100644
> index 0000000..647bc2f
> --- /dev/null
> +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c
> @@ -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
> index 0000000..19f095e
> --- /dev/null
> +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
> @@ -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
> index 0000000..f99a14f
> --- /dev/null
> +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni
> @@ -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
> index 0000000..ee4c49f
> --- /dev/null
> +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni
> @@ -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
> index 0000000..a8f7e43
> --- /dev/null
> +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni
> @@ -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
> index 0000000..1132cac
> --- /dev/null
> +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c
> @@ -0,0 +1,1841 @@
> +/** @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
> +  )
> +{
> +  UINTN Size;
> +
> +  Size = UnicodeSPrint (
> +            Buffer,
> +            BufferSize,
> +            L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
> +            (UINTN)Guid->Data1,
> +            (UINTN)Guid->Data2,
> +            (UINTN)Guid->Data3,
> +            (UINTN)Guid->Data4[0],
> +            (UINTN)Guid->Data4[1],
> +            (UINTN)Guid->Data4[2],
> +            (UINTN)Guid->Data4[3],
> +            (UINTN)Guid->Data4[4],
> +            (UINTN)Guid->Data4[5],
> +            (UINTN)Guid->Data4[6],
> +            (UINTN)Guid->Data4[7]
> +            );
> +
> +  //
> +  // SPrint will null terminate the string. The -1 skips the null
> +  //
> +  return Size - 1;
> +}
> +
> +/**
> +  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
> index 0000000..398f7b6
> --- /dev/null
> +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h
> @@ -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
> index 0000000..f453201
> --- /dev/null
> +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h
> @@ -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
> index 0000000..fb130d9
> --- /dev/null
> +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr
> @@ -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;
> --
> 1.9.5.msysgit.1


  reply	other threads:[~2016-12-22  3:13 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-14  7:34 [Patch 00/10] Sync staging/HTTPS-TLS feature into edk2 master Jiaxin Wu
2016-12-14  7:34 ` [Patch 01/10] MdePkg: Add TLS related protocol definition Jiaxin Wu
2016-12-14  8:36   ` Long, Qin
2016-12-14  8:39     ` Wu, Jiaxin
2016-12-15  8:34       ` Ye, Ting
2016-12-14  8:43   ` Fu, Siyuan
2016-12-14  7:34 ` [Patch 02/10] MdePkg: Add a header to standardize TLS definitions Jiaxin Wu
2016-12-14  8:42   ` Long, Qin
2016-12-14  8:43   ` Fu, Siyuan
2016-12-15  8:35   ` Ye, Ting
2016-12-14  7:34 ` [Patch 03/10] CryptoPkg: Enable ssl build in OpensslLib directly Jiaxin Wu
2016-12-15  8:37   ` Ye, Ting
2016-12-14  7:34 ` [Patch 04/10] CryptoPkg: Add new TlsLib library Jiaxin Wu
2016-12-16  2:10   ` Ye, Ting
2016-12-16  2:51     ` Wu, Jiaxin
2016-12-14  7:34 ` [Patch 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL Jiaxin Wu
2016-12-14  8:41   ` Fu, Siyuan
2016-12-15  7:24     ` Wu, Jiaxin
2016-12-14  7:34 ` [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to support TLS auth configuration Jiaxin Wu
2016-12-15  2:22   ` Fu, Siyuan
2016-12-22  2:52     ` Ye, Ting
2016-12-22  3:13       ` Wu, Jiaxin [this message]
2016-12-14  7:34 ` [Patch 07/10] NetworkPkg/HttpDxe: HTTPS support over IPv4 and IPv6 Jiaxin Wu
2016-12-15  2:39   ` Fu, Siyuan
2016-12-15  7:14     ` Wu, Jiaxin
2016-12-22  7:33   ` Ye, Ting
2016-12-22  8:30     ` Wu, Jiaxin
2016-12-14  7:34 ` [Patch 08/10] NetworkPkg/NetworkPkg.dsc: Enable TlsDxe and TlsAuthConfigDxe module Jiaxin Wu
2016-12-15  2:39   ` Fu, Siyuan
2016-12-22  7:37   ` Ye, Ting
2016-12-14  7:34 ` [Patch 09/10] Nt32Pkg/Nt32Pkg.dsc: Remove the flag for OpensslLib and BaseCryptLib Jiaxin Wu
2016-12-14  7:56   ` Ni, Ruiyu
2016-12-15  8:25   ` Long, Qin
2016-12-22  7:39   ` Ye, Ting
2016-12-14  7:34 ` [Patch 10/10] Nt32Pkg: Enable HTTPS boot feature for Nt32 platform Jiaxin Wu
2016-12-14  7:44   ` Yao, Jiewen
2016-12-14  7:46     ` Wu, Jiaxin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=895558F6EA4E3B41AC93A00D163B72741628DE02@SHSMSX103.ccr.corp.intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox