public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH 0/4] CryptoPkg: add more X509 functions.
@ 2022-09-25  8:54 Qi Zhang
  2022-09-25  8:54 ` [PATCH 1/4] CryptoPkg: add new X509 function definition Qi Zhang
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Qi Zhang @ 2022-09-25  8:54 UTC (permalink / raw)
  To: devel; +Cc: Qi Zhang, Jiewen Yao, Jian J Wang, Xiaoyu Lu, Guomin Jiang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4082

This patch serial is to add more CryptoX509 functions.

Tested by:
1. https://github.com/tianocore/edk2-staging/tree/DeviceSecurity.
2. Unit test: CryptoPkg/Test/UnitTest/Library/BaseCryptLib/X509Tests.c

Review PR: https://github.com/tianocore/edk2/pull/3380.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Signed-off-by: Qi Zhang <qi1.zhang@intel.com>

Qi Zhang (4):
  CryptoPkg: add new X509 function definition.
  CryptoPkg: add new X509 function.
  CryptoPkg: add new X509 function to Crypto Service.
  CryptoPkg: add Unit Test for X509 new function.

 CryptoPkg/Driver/Crypto.c                     |  430 +++++++
 CryptoPkg/Include/Library/BaseCryptLib.h      |  374 ++++++
 .../Pcd/PcdCryptoServiceFamilyEnable.h        |   34 +-
 CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c | 1036 +++++++++++++++++
 .../Library/BaseCryptLib/Pk/CryptX509Null.c   |  429 +++++++
 .../BaseCryptLibNull/Pk/CryptX509Null.c       |  429 +++++++
 .../BaseCryptLibOnProtocolPpi/CryptLib.c      |  415 +++++++
 CryptoPkg/Private/Protocol/Crypto.h           |  790 +++++++++----
 .../BaseCryptLib/BaseCryptLibUnitTests.c      |    1 +
 .../Library/BaseCryptLib/TestBaseCryptLib.h   |    3 +
 .../BaseCryptLib/TestBaseCryptLibHost.inf     |    1 +
 .../BaseCryptLib/TestBaseCryptLibShell.inf    |    1 +
 .../UnitTest/Library/BaseCryptLib/X509Tests.c |  631 ++++++++++
 13 files changed, 4364 insertions(+), 210 deletions(-)
 create mode 100644 CryptoPkg/Test/UnitTest/Library/BaseCryptLib/X509Tests.c

-- 
2.26.2.windows.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/4] CryptoPkg: add new X509 function definition.
  2022-09-25  8:54 [PATCH 0/4] CryptoPkg: add more X509 functions Qi Zhang
@ 2022-09-25  8:54 ` Qi Zhang
  2022-10-10  0:34   ` Yao, Jiewen
  2022-09-25  8:54 ` [PATCH 2/4] CryptoPkg: add new X509 function Qi Zhang
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Qi Zhang @ 2022-09-25  8:54 UTC (permalink / raw)
  To: devel; +Cc: Qi Zhang, Jiewen Yao, Jian J Wang, Xiaoyu Lu, Guomin Jiang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4082

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Signed-off-by: Qi Zhang <qi1.zhang@intel.com>
---
 CryptoPkg/Include/Library/BaseCryptLib.h | 374 +++++++++++++++++++++++
 1 file changed, 374 insertions(+)

diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h
index 3026299e29..d7bf29c93f 100644
--- a/CryptoPkg/Include/Library/BaseCryptLib.h
+++ b/CryptoPkg/Include/Library/BaseCryptLib.h
@@ -2459,6 +2459,380 @@ ImageTimestampVerify (
   OUT EFI_TIME     *SigningTime
   );
 
+/**
+  Retrieve the version from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     Version      Pointer to the retrieved version integer.
+
+  @retval TRUE           The certificate version retrieved successfully.
+  @retval FALSE          If  Cert is NULL or CertSize is Zero.
+  @retval FALSE          The operation is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetVersion (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINTN        *Version
+  );
+
+/**
+  Retrieve the serialNumber from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     SerialNumber  Pointer to the retrieved certificate SerialNumber bytes.
+  @param[in, out] SerialNumberSize  The size in bytes of the SerialNumber buffer on input,
+                               and the size of buffer returned SerialNumber on output.
+
+  @retval TRUE                     The certificate serialNumber retrieved successfully.
+  @retval FALSE                    If Cert is NULL or CertSize is Zero.
+                                   If SerialNumberSize is NULL.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SerialNumber exists.
+  @retval FALSE                    If the SerialNumber is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   SerialNumberSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSerialNumber (
+  IN      CONST UINT8 *Cert,
+  IN      UINTN CertSize,
+  OUT     UINT8 *SerialNumber, OPTIONAL
+  IN OUT  UINTN         *SerialNumberSize
+  );
+
+/**
+  Retrieve the issuer bytes from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     CertIssuer  Pointer to the retrieved certificate subject bytes.
+  @param[in, out] CertIssuerSize  The size in bytes of the CertIssuer buffer on input,
+                               and the size of buffer returned CertSubject on output.
+
+  @retval  TRUE   The certificate issuer retrieved successfully.
+  @retval  FALSE  Invalid certificate, or the CertIssuerSize is too small for the result.
+                  The CertIssuerSize will be updated with the required size.
+  @retval  FALSE  This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetIssuerName (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINT8        *CertIssuer,
+  IN OUT  UINTN        *CertIssuerSize
+  );
+
+/**
+  Retrieve the Signature Algorithm from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Oid              Signature Algorithm Object identifier buffer.
+  @param[in,out]  OidSize          Signature Algorithm Object identifier buffer size
+
+  @retval TRUE           The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If OidSize is NULL.
+                                   If Oid is not NULL and *OidSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SignatureType.
+  @retval FALSE                    If the Oid is NULL. The required buffer size
+                                   is returned in the OidSize.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSignatureAlgorithm (
+  IN CONST UINT8 *Cert,
+  IN       UINTN CertSize,
+  OUT   UINT8 *Oid, OPTIONAL
+  IN OUT   UINTN       *OidSize
+  );
+
+/**
+  Retrieve Extension data from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[in]      Oid              Object identifier buffer
+  @param[in]      OidSize          Object identifier buffer size
+  @param[out]     ExtensionData    Extension bytes.
+  @param[in, out] ExtensionDataSize Extension bytes size.
+
+  @retval TRUE                     The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If ExtensionDataSize is NULL.
+                                   If ExtensionData is not NULL and *ExtensionDataSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no Extension entry match Oid.
+  @retval FALSE                    If the ExtensionData is NULL. The required buffer size
+                                   is returned in the ExtensionDataSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtensionData (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     CONST UINT8  *Oid,
+  IN     UINTN        OidSize,
+  OUT UINT8           *ExtensionData,
+  IN OUT UINTN        *ExtensionDataSize
+  );
+
+/**
+  Retrieve the Validity from one X.509 certificate
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[in]      From         notBefore Pointer to DateTime object.
+  @param[in,out]  FromSize     notBefore DateTime object size.
+  @param[in]      To           notAfter Pointer to DateTime object.
+  @param[in,out]  ToSize       notAfter DateTime object size.
+
+  Note: X509CompareDateTime to compare DateTime oject
+        x509SetDateTime to get a DateTime object from a DateTimeStr
+
+  @retval  TRUE   The certificate Validity retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Validity retrieve failed.
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetValidity (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     UINT8        *From,
+  IN OUT UINTN        *FromSize,
+  IN     UINT8        *To,
+  IN OUT UINTN        *ToSize
+  );
+
+/**
+  Format a DateTime object into DataTime Buffer
+
+  If DateTimeStr is NULL, then return FALSE.
+  If DateTimeSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      DateTimeStr      DateTime string like YYYYMMDDhhmmssZ
+                                   Ref: https://www.w3.org/TR/NOTE-datetime
+                                   Z stand for UTC time
+  @param[out]     DateTime         Pointer to a DateTime object.
+  @param[in,out]  DateTimeSize     DateTime object buffer size.
+
+  @retval TRUE                     The DateTime object create successfully.
+  @retval FALSE                    If DateTimeStr is NULL.
+                                   If DateTimeSize is NULL.
+                                   If DateTime is not NULL and *DateTimeSize is 0.
+                                   If Year Month Day Hour Minute Second combination is invalid datetime.
+  @retval FALSE                    If the DateTime is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   DateTimeSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509SetDateTime (
+  IN   CHAR8    *DateTimeStr,
+  OUT  VOID     *DateTime,
+  IN OUT UINTN  *DateTimeSize
+  );
+
+/**
+  Compare DateTime1 object and DateTime2 object.
+
+  If DateTime1 is NULL, then return -2.
+  If DateTime2 is NULL, then return -2.
+  If DateTime1 == DateTime2, then return 0
+  If DateTime1 > DateTime2, then return 1
+  If DateTime1 < DateTime2, then return -1
+
+  @param[in]      DateTime1         Pointer to a DateTime Ojbect
+  @param[in]      DateTime2         Pointer to a DateTime Object
+
+  @retval  0      If DateTime1 == DateTime2
+  @retval  1      If DateTime1 > DateTime2
+  @retval  -1     If DateTime1 < DateTime2
+**/
+INT32
+EFIAPI
+X509CompareDateTime (
+  IN  CONST  VOID  *DateTime1,
+  IN  CONST  VOID  *DateTime2
+  );
+
+/**
+  Retrieve the Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage (CRYPTO_X509_KU_*)
+
+  @retval  TRUE   The certificate Key Usage retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Usage is NULL
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetKeyUsage (
+  IN    CONST UINT8  *Cert,
+  IN    UINTN        CertSize,
+  OUT   UINTN        *Usage
+  );
+
+/**
+  Retrieve the Extended Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage bytes.
+  @param[in, out] UsageSize        Key Usage buffer sizs in bytes.
+
+  @retval TRUE                     The Usage bytes retrieve successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If CertSize is NULL.
+                                   If Usage is not NULL and *UsageSize is 0.
+                                   If Cert is invalid.
+  @retval FALSE                    If the Usage is NULL. The required buffer size
+                                   is returned in the UsageSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtendedKeyUsage (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  OUT UINT8           *Usage,
+  IN OUT UINTN        *UsageSize
+  );
+
+/**
+  Verify one X509 certificate was issued by the trusted CA.
+  @param[in]      RootCert          Trusted Root Certificate buffer
+
+  @param[in]      RootCertLength    Trusted Root Certificate buffer length
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @retval  TRUE   All cerificates was issued by the first certificate in X509Certchain.
+  @retval  FALSE  Invalid certificate or the certificate was not issued by the given
+                  trusted CA.
+**/
+BOOLEAN
+EFIAPI
+X509VerifyCertChain (
+  IN CONST UINT8  *RootCert,
+  IN UINTN        RootCertLength,
+  IN CONST UINT8  *CertChain,
+  IN UINTN        CertChainLength
+  );
+
+/**
+  Get one X509 certificate from CertChain.
+
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @param[in]      CertIndex         Index of certificate. If index is -1 indecate the
+                                    last certificate in CertChain.
+
+  @param[out]     Cert              The certificate at the index of CertChain.
+  @param[out]     CertLength        The length certificate at the index of CertChain.
+
+  @retval  TRUE   Success.
+  @retval  FALSE  Failed to get certificate from certificate chain.
+**/
+BOOLEAN
+EFIAPI
+X509GetCertFromCertChain (
+  IN CONST UINT8   *CertChain,
+  IN UINTN         CertChainLength,
+  IN CONST INT32   CertIndex,
+  OUT CONST UINT8  **Cert,
+  OUT UINTN        *CertLength
+  );
+
+/**
+  Retrieve the tag and length of the tag.
+
+  @param Ptr      The position in the ASN.1 data
+  @param End      End of data
+  @param Length   The variable that will receive the length
+  @param Tag      The expected tag
+
+  @retval      TRUE   Get tag successful
+  @retval      FALSe  Failed to get tag or tag not match
+**/
+BOOLEAN
+EFIAPI
+Asn1GetTag (
+  IN OUT UINT8   **Ptr,
+  IN     UINT8   *End,
+  OUT UINTN      *Length,
+  IN     UINT32  Tag
+  );
+
+/**
+  Retrieve the basic constraints from one X.509 certificate.
+
+  @param[in]      Cert                     Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize                 size of the X509 certificate in bytes.
+  @param[out]     BasicConstraints         basic constraints bytes.
+  @param[in, out] BasicConstraintsSize     basic constraints buffer sizs in bytes.
+
+  @retval TRUE                     The basic constraints retrieve successfully.
+  @retval FALSE                    If cert is NULL.
+                                   If cert_size is NULL.
+                                   If basic_constraints is not NULL and *basic_constraints_size is 0.
+                                   If cert is invalid.
+  @retval FALSE                    The required buffer size is small.
+                                   The return buffer size is basic_constraints_size parameter.
+  @retval FALSE                    If no Extension entry match oid.
+  @retval FALSE                    The operation is not supported.
+ **/
+BOOLEAN
+EFIAPI
+X509GetExtendedBasicConstraints             (
+  CONST UINT8  *Cert,
+  UINTN        CertSize,
+  UINT8        *BasicConstraints,
+  UINTN        *BasicConstraintsSize
+  );
+
 // =====================================================================================
 //    DH Key Exchange Primitive
 // =====================================================================================
-- 
2.26.2.windows.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/4] CryptoPkg: add new X509 function.
  2022-09-25  8:54 [PATCH 0/4] CryptoPkg: add more X509 functions Qi Zhang
  2022-09-25  8:54 ` [PATCH 1/4] CryptoPkg: add new X509 function definition Qi Zhang
@ 2022-09-25  8:54 ` Qi Zhang
  2022-09-25  8:54 ` [PATCH 3/4] CryptoPkg: add new X509 function to Crypto Service Qi Zhang
  2022-09-25  8:54 ` [PATCH 4/4] CryptoPkg: add Unit Test for X509 new function Qi Zhang
  3 siblings, 0 replies; 7+ messages in thread
From: Qi Zhang @ 2022-09-25  8:54 UTC (permalink / raw)
  To: devel; +Cc: Qi Zhang, Jiewen Yao, Jian J Wang, Xiaoyu Lu, Guomin Jiang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4082

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Signed-off-by: Qi Zhang <qi1.zhang@intel.com>
---
 CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c | 1036 +++++++++++++++++
 .../Library/BaseCryptLib/Pk/CryptX509Null.c   |  429 +++++++
 .../BaseCryptLibNull/Pk/CryptX509Null.c       |  429 +++++++
 3 files changed, 1894 insertions(+)

diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c
index e6bb45e641..4cb3c9f814 100644
--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c
@@ -8,8 +8,22 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 
 #include "InternalCryptLib.h"
 #include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <crypto/asn1.h>
+#include <openssl/asn1.h>
 #include <openssl/rsa.h>
 
+/* OID*/
+#define OID_EXT_KEY_USAGE      { 0x55, 0x1D, 0x25 }
+#define OID_BASIC_CONSTRAINTS  { 0x55, 0x1D, 0x13 }
+
+static CONST UINT8  mOidExtKeyUsage[]      = OID_EXT_KEY_USAGE;
+static CONST UINT8  mOidBasicConstraints[] = OID_BASIC_CONSTRAINTS;
+
+#define CRYPTO_ASN1_TAG_CLASS_MASK  0xC0
+#define CRYPTO_ASN1_TAG_PC_MASK     0x20
+#define CRYPTO_ASN1_TAG_VALUE_MASK  0x1F
+
 /**
   Construct a X509 object from DER-encoded certificate data.
 
@@ -842,3 +856,1025 @@ X509GetTBSCert (
 
   return TRUE;
 }
+
+/**
+  Retrieve the version from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     Version      Pointer to the retrieved version integer.
+
+  @retval TRUE           The certificate version retrieved successfully.
+  @retval FALSE          If  Cert is NULL or CertSize is Zero.
+  @retval FALSE          The operation is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetVersion (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINTN        *Version
+  )
+{
+  BOOLEAN  Status;
+  X509     *X509Cert;
+
+  X509Cert = NULL;
+  Status   = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
+  if ((X509Cert == NULL) || (!Status)) {
+    //
+    // Invalid X.509 Certificate
+    //
+    Status = FALSE;
+  }
+
+  if (Status) {
+    *Version = X509_get_version (X509Cert);
+  }
+
+  if (X509Cert != NULL) {
+    X509_free (X509Cert);
+  }
+
+  return Status;
+}
+
+/**
+  Retrieve the serialNumber from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     SerialNumber  Pointer to the retrieved certificate SerialNumber bytes.
+  @param[in, out] SerialNumberSize  The size in bytes of the SerialNumber buffer on input,
+                               and the size of buffer returned SerialNumber on output.
+
+  @retval TRUE                     The certificate serialNumber retrieved successfully.
+  @retval FALSE                    If Cert is NULL or CertSize is Zero.
+                                   If SerialNumberSize is NULL.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SerialNumber exists.
+  @retval FALSE                    If the SerialNumber is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   SerialNumberSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSerialNumber (
+  IN      CONST UINT8 *Cert,
+  IN      UINTN CertSize,
+  OUT     UINT8 *SerialNumber, OPTIONAL
+  IN OUT  UINTN         *SerialNumberSize
+  )
+{
+  BOOLEAN       Status;
+  X509          *X509Cert;
+  ASN1_INTEGER  *Asn1Integer;
+
+  Status = FALSE;
+  //
+  // Check input parameters.
+  //
+  if ((Cert == NULL) || (SerialNumberSize == NULL)) {
+    return Status;
+  }
+
+  X509Cert = NULL;
+
+  //
+  // Read DER-encoded X509 Certificate and Construct X509 object.
+  //
+  Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
+  if ((X509Cert == NULL) || (!Status)) {
+    *SerialNumberSize = 0;
+    Status            = FALSE;
+    goto _Exit;
+  }
+
+  //
+  // Retrieve subject name from certificate object.
+  //
+  Asn1Integer = X509_get_serialNumber (X509Cert);
+  if (Asn1Integer == NULL) {
+    *SerialNumberSize = 0;
+    Status            = FALSE;
+    goto _Exit;
+  }
+
+  if (*SerialNumberSize < (UINTN)Asn1Integer->length) {
+    *SerialNumberSize = (UINTN)Asn1Integer->length;
+    Status            = FALSE;
+    goto _Exit;
+  }
+
+  if (SerialNumber != NULL) {
+    CopyMem (SerialNumber, Asn1Integer->data, *SerialNumberSize);
+    Status = TRUE;
+  }
+
+  *SerialNumberSize = (UINTN)Asn1Integer->length;
+
+_Exit:
+  //
+  // Release Resources.
+  //
+  if (X509Cert != NULL) {
+    X509_free (X509Cert);
+  }
+
+  return Status;
+}
+
+/**
+  Retrieve the issuer bytes from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     CertIssuer  Pointer to the retrieved certificate subject bytes.
+  @param[in, out] CertIssuerSize  The size in bytes of the CertIssuer buffer on input,
+                               and the size of buffer returned CertSubject on output.
+
+  @retval  TRUE   The certificate issuer retrieved successfully.
+  @retval  FALSE  Invalid certificate, or the CertIssuerSize is too small for the result.
+                  The CertIssuerSize will be updated with the required size.
+  @retval  FALSE  This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetIssuerName (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINT8        *CertIssuer,
+  IN OUT  UINTN        *CertIssuerSize
+  )
+{
+  BOOLEAN    Status;
+  X509       *X509Cert;
+  X509_NAME  *X509Name;
+  UINTN      X509NameSize;
+
+  //
+  // Check input parameters.
+  //
+  if ((Cert == NULL) || (CertIssuerSize == NULL)) {
+    return FALSE;
+  }
+
+  X509Cert = NULL;
+
+  //
+  // Read DER-encoded X509 Certificate and Construct X509 object.
+  //
+  Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
+  if ((X509Cert == NULL) || (!Status)) {
+    Status = FALSE;
+    goto _Exit;
+  }
+
+  Status = FALSE;
+
+  //
+  // Retrieve subject name from certificate object.
+  //
+  X509Name = X509_get_subject_name (X509Cert);
+  if (X509Name == NULL) {
+    goto _Exit;
+  }
+
+  X509NameSize = i2d_X509_NAME (X509Name, NULL);
+  if (*CertIssuerSize < X509NameSize) {
+    *CertIssuerSize = X509NameSize;
+    goto _Exit;
+  }
+
+  *CertIssuerSize = X509NameSize;
+  if (CertIssuer != NULL) {
+    i2d_X509_NAME (X509Name, &CertIssuer);
+    Status = TRUE;
+  }
+
+_Exit:
+  //
+  // Release Resources.
+  //
+  if (X509Cert != NULL) {
+    X509_free (X509Cert);
+  }
+
+  return Status;
+}
+
+/**
+  Retrieve the Signature Algorithm from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Oid              Signature Algorithm Object identifier buffer.
+  @param[in,out]  OidSize          Signature Algorithm Object identifier buffer size
+
+  @retval TRUE           The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If OidSize is NULL.
+                                   If Oid is not NULL and *OidSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SignatureType.
+  @retval FALSE                    If the Oid is NULL. The required buffer size
+                                   is returned in the OidSize.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSignatureAlgorithm (
+  IN CONST UINT8 *Cert,
+  IN       UINTN CertSize,
+  OUT   UINT8 *Oid, OPTIONAL
+  IN OUT   UINTN       *OidSize
+  )
+{
+  BOOLEAN      Status;
+  X509         *X509Cert;
+  int          Nid;
+  ASN1_OBJECT  *Asn1Obj;
+
+  //
+  // Check input parameters.
+  //
+  if ((Cert == NULL) || (OidSize == NULL) || (CertSize == 0)) {
+    return FALSE;
+  }
+
+  X509Cert = NULL;
+  Status   = FALSE;
+
+  //
+  // Read DER-encoded X509 Certificate and Construct X509 object.
+  //
+  Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
+  if ((X509Cert == NULL) || (!Status)) {
+    Status = FALSE;
+    goto _Exit;
+  }
+
+  //
+  // Retrieve subject name from certificate object.
+  //
+  Nid = X509_get_signature_nid (X509Cert);
+  if (Nid == NID_undef) {
+    *OidSize = 0;
+    Status   = FALSE;
+    goto _Exit;
+  }
+
+  Asn1Obj = OBJ_nid2obj (Nid);
+  if (Asn1Obj == NULL) {
+    *OidSize = 0;
+    Status   = FALSE;
+    goto _Exit;
+  }
+
+  if (*OidSize < (UINTN)Asn1Obj->length) {
+    *OidSize = Asn1Obj->length;
+    Status   = FALSE;
+    goto _Exit;
+  }
+
+  if (Oid != NULL) {
+    CopyMem (Oid, Asn1Obj->data, Asn1Obj->length);
+  }
+
+  *OidSize = Asn1Obj->length;
+  Status   = TRUE;
+
+_Exit:
+  //
+  // Release Resources.
+  //
+  if (X509Cert != NULL) {
+    X509_free (X509Cert);
+  }
+
+  return Status;
+}
+
+/**
+  Retrieve Extension data from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[in]      Oid              Object identifier buffer
+  @param[in]      OidSize          Object identifier buffer size
+  @param[out]     ExtensionData    Extension bytes.
+  @param[in, out] ExtensionDataSize Extension bytes size.
+
+  @retval TRUE                     The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If ExtensionDataSize is NULL.
+                                   If ExtensionData is not NULL and *ExtensionDataSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no Extension entry match Oid.
+  @retval FALSE                    If the ExtensionData is NULL. The required buffer size
+                                   is returned in the ExtensionDataSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtensionData (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     CONST UINT8  *Oid,
+  IN     UINTN        OidSize,
+  OUT UINT8           *ExtensionData,
+  IN OUT UINTN        *ExtensionDataSize
+  )
+{
+  BOOLEAN  Status;
+  INTN     i;
+  X509     *X509Cert;
+
+  CONST STACK_OF (X509_EXTENSION) *Extensions;
+  ASN1_OBJECT        *Asn1Obj;
+  ASN1_OCTET_STRING  *Asn1Oct;
+  X509_EXTENSION     *Ext;
+  UINTN              ObjLength;
+  UINTN              OctLength;
+
+  //
+  // Check input parameters.
+  //
+  if ((Cert == NULL) || (CertSize == 0) || (Oid == NULL) || (OidSize == 0) || (ExtensionDataSize == NULL)) {
+    return FALSE;
+  }
+
+  X509Cert = NULL;
+  Status   = FALSE;
+
+  //
+  // Read DER-encoded X509 Certificate and Construct X509 object.
+  //
+  Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
+  if ((X509Cert == NULL) || (!Status)) {
+    *ExtensionDataSize = 0;
+    goto Cleanup;
+  }
+
+  //
+  // Retrieve Extensions from certificate object.
+  //
+  Extensions = X509_get0_extensions (X509Cert);
+  if (sk_X509_EXTENSION_num (Extensions) <= 0) {
+    *ExtensionDataSize = 0;
+    goto Cleanup;
+  }
+
+  //
+  // Traverse Extensions
+  //
+  Status    = FALSE;
+  Asn1Oct   = NULL;
+  OctLength = 0;
+  for (i = 0; i < sk_X509_EXTENSION_num (Extensions); i++) {
+    Ext = sk_X509_EXTENSION_value (Extensions, (int)i);
+    if (Ext == NULL) {
+      continue;
+    }
+
+    Asn1Obj = X509_EXTENSION_get_object (Ext);
+    if (Asn1Obj == NULL) {
+      continue;
+    }
+
+    Asn1Oct = X509_EXTENSION_get_data (Ext);
+    if (Asn1Oct == NULL) {
+      continue;
+    }
+
+    ObjLength = OBJ_length (Asn1Obj);
+    OctLength = ASN1_STRING_length (Asn1Oct);
+    if ((OidSize == ObjLength) && (CompareMem (OBJ_get0_data (Asn1Obj), Oid, OidSize) == 0)) {
+      //
+      // Extension Found
+      //
+      Status = TRUE;
+      break;
+    }
+
+    //
+    // reset to 0 if not found
+    //
+    OctLength = 0;
+  }
+
+  if (Status) {
+    if (*ExtensionDataSize < OctLength) {
+      *ExtensionDataSize = OctLength;
+      Status             = FALSE;
+      goto Cleanup;
+    }
+
+    if (Asn1Oct != NULL) {
+      CopyMem (ExtensionData, ASN1_STRING_get0_data (Asn1Oct), OctLength);
+    }
+
+    *ExtensionDataSize = OctLength;
+  } else {
+    *ExtensionDataSize = 0;
+  }
+
+Cleanup:
+  //
+  // Release Resources.
+  //
+  if (X509Cert != NULL) {
+    X509_free (X509Cert);
+  }
+
+  return Status;
+}
+
+/**
+  Retrieve the Extended Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage bytes.
+  @param[in, out] UsageSize        Key Usage buffer sizs in bytes.
+
+  @retval TRUE                     The Usage bytes retrieve successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If CertSize is NULL.
+                                   If Usage is not NULL and *UsageSize is 0.
+                                   If Cert is invalid.
+  @retval FALSE                    If the Usage is NULL. The required buffer size
+                                   is returned in the UsageSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtendedKeyUsage (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  OUT UINT8           *Usage,
+  IN OUT UINTN        *UsageSize
+  )
+{
+  BOOLEAN  Status;
+
+  Status = X509GetExtensionData (Cert, CertSize, mOidExtKeyUsage, sizeof (mOidExtKeyUsage), Usage, UsageSize);
+  return Status;
+}
+
+/**
+  Retrieve the Validity from one X.509 certificate
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     From         notBefore Pointer to DateTime object.
+  @param[in,out]  FromSize     notBefore DateTime object size.
+  @param[out]     To           notAfter Pointer to DateTime object.
+  @param[in,out]  ToSize       notAfter DateTime object size.
+
+  Note: X509CompareDateTime to compare DateTime oject
+        x509SetDateTime to get a DateTime object from a DateTimeStr
+
+  @retval  TRUE   The certificate Validity retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Validity retrieve failed.
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetValidity  (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     UINT8        *From,
+  IN OUT UINTN        *FromSize,
+  IN     UINT8        *To,
+  IN OUT UINTN        *ToSize
+  )
+{
+  BOOLEAN          Status;
+  X509             *X509Cert;
+  CONST ASN1_TIME  *F;
+  CONST ASN1_TIME  *T;
+  UINTN            TSize;
+  UINTN            FSize;
+
+  //
+  // Check input parameters.
+  //
+  if ((Cert == NULL) || (FromSize == NULL) || (ToSize == NULL) || (CertSize == 0)) {
+    return FALSE;
+  }
+
+  X509Cert = NULL;
+  Status   = FALSE;
+
+  //
+  // Read DER-encoded X509 Certificate and Construct X509 object.
+  //
+  Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
+  if ((X509Cert == NULL) || (!Status)) {
+    goto _Exit;
+  }
+
+  //
+  // Retrieve Validity from/to from certificate object.
+  //
+  F = X509_get0_notBefore (X509Cert);
+  T = X509_get0_notAfter (X509Cert);
+
+  if ((F == NULL) || (T == NULL)) {
+    goto _Exit;
+  }
+
+  FSize = sizeof (ASN1_TIME) + F->length;
+  if (*FromSize < FSize) {
+    *FromSize = FSize;
+    goto _Exit;
+  }
+
+  *FromSize = FSize;
+  if (From != NULL) {
+    CopyMem (From, F, sizeof (ASN1_TIME));
+    ((ASN1_TIME *)From)->data = From + sizeof (ASN1_TIME);
+    CopyMem (From + sizeof (ASN1_TIME), F->data, F->length);
+  }
+
+  TSize = sizeof (ASN1_TIME) + T->length;
+  if (*ToSize < TSize) {
+    *ToSize = TSize;
+    goto _Exit;
+  }
+
+  *ToSize = TSize;
+  if (To != NULL) {
+    CopyMem (To, T, sizeof (ASN1_TIME));
+    ((ASN1_TIME *)To)->data = To + sizeof (ASN1_TIME);
+    CopyMem (To + sizeof (ASN1_TIME), T->data, T->length);
+  }
+
+  Status = TRUE;
+
+_Exit:
+  //
+  // Release Resources.
+  //
+  if (X509Cert != NULL) {
+    X509_free (X509Cert);
+  }
+
+  return Status;
+}
+
+/**
+  Format a DateTime object into DataTime Buffer
+
+  If DateTimeStr is NULL, then return FALSE.
+  If DateTimeSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      DateTimeStr      DateTime string like YYYYMMDDhhmmssZ
+                                   Ref: https://www.w3.org/TR/NOTE-datetime
+                                   Z stand for UTC time
+  @param[out]     DateTime         Pointer to a DateTime object.
+  @param[in,out]  DateTimeSize     DateTime object buffer size.
+
+  @retval TRUE                     The DateTime object create successfully.
+  @retval FALSE                    If DateTimeStr is NULL.
+                                   If DateTimeSize is NULL.
+                                   If DateTime is not NULL and *DateTimeSize is 0.
+                                   If Year Month Day Hour Minute Second combination is invalid datetime.
+  @retval FALSE                    If the DateTime is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   DateTimeSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509SetDateTime (
+  IN     CHAR8  *DateTimeStr,
+  OUT VOID      *DateTime,
+  IN OUT UINTN  *DateTimeSize
+  )
+{
+  BOOLEAN    Status;
+  INT32      Ret;
+  ASN1_TIME  *Dt;
+  UINTN      DSize;
+
+  Dt     = NULL;
+  Status = FALSE;
+
+  Dt = ASN1_TIME_new ();
+  if (Dt == NULL) {
+    Status = FALSE;
+    goto Cleanup;
+  }
+
+  Ret = ASN1_TIME_set_string_X509 (Dt, DateTimeStr);
+  if (Ret != 1) {
+    Status = FALSE;
+    goto Cleanup;
+  }
+
+  DSize = sizeof (ASN1_TIME) + Dt->length;
+  if (*DateTimeSize < DSize) {
+    *DateTimeSize = DSize;
+    Status        = FALSE;
+    goto Cleanup;
+  }
+
+  *DateTimeSize = DSize;
+  if (DateTime != NULL) {
+    CopyMem (DateTime, Dt, sizeof (ASN1_TIME));
+    ((ASN1_TIME *)DateTime)->data = (UINT8 *)DateTime + sizeof (ASN1_TIME);
+    CopyMem ((UINT8 *)DateTime + sizeof (ASN1_TIME), Dt->data, Dt->length);
+  }
+
+  Status = TRUE;
+
+Cleanup:
+  if (Dt != NULL) {
+    ASN1_TIME_free (Dt);
+  }
+
+  return Status;
+}
+
+/**
+  Compare DateTime1 object and DateTime2 object.
+
+  If DateTime1 is NULL, then return -2.
+  If DateTime2 is NULL, then return -2.
+  If DateTime1 == DateTime2, then return 0
+  If DateTime1 > DateTime2, then return 1
+  If DateTime1 < DateTime2, then return -1
+
+  @param[in]      DateTime1         Pointer to a DateTime Ojbect
+  @param[in]      DateTime2         Pointer to a DateTime Object
+
+  @retval  0      If DateTime1 == DateTime2
+  @retval  1      If DateTime1 > DateTime2
+  @retval  -1     If DateTime1 < DateTime2
+**/
+INT32
+EFIAPI
+X509CompareDateTime (
+  IN CONST  VOID  *DateTime1,
+  IN CONST  VOID  *DateTime2
+  )
+{
+  return (INT32)ASN1_TIME_compare (DateTime1, DateTime2);
+}
+
+/**
+  Retrieve the Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage (CRYPTO_X509_KU_*)
+
+  @retval  TRUE   The certificate Key Usage retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Usage is NULL
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetKeyUsage (
+  IN    CONST UINT8  *Cert,
+  IN    UINTN        CertSize,
+  OUT   UINTN        *Usage
+  )
+{
+  BOOLEAN  Status;
+  X509     *X509Cert;
+
+  //
+  // Check input parameters.
+  //
+  if ((Cert == NULL) || (Usage == NULL)) {
+    return FALSE;
+  }
+
+  X509Cert = NULL;
+  Status   = FALSE;
+
+  //
+  // Read DER-encoded X509 Certificate and Construct X509 object.
+  //
+  Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
+  if ((X509Cert == NULL) || (!Status)) {
+    goto _Exit;
+  }
+
+  //
+  // Retrieve subject name from certificate object.
+  //
+  *Usage = X509_get_key_usage (X509Cert);
+  if (*Usage == NID_undef) {
+    goto _Exit;
+  }
+
+  Status = TRUE;
+
+_Exit:
+  //
+  // Release Resources.
+  //
+  if (X509Cert != NULL) {
+    X509_free (X509Cert);
+  }
+
+  return Status;
+}
+
+/**
+  Verify one X509 certificate was issued by the trusted CA.
+  @param[in]      RootCert          Trusted Root Certificate buffer
+
+  @param[in]      RootCertLength    Trusted Root Certificate buffer length
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @retval  TRUE   All cerificates was issued by the first certificate in X509Certchain.
+  @retval  FALSE  Invalid certificate or the certificate was not issued by the given
+                  trusted CA.
+**/
+BOOLEAN
+EFIAPI
+X509VerifyCertChain (
+  IN CONST UINT8  *RootCert,
+  IN UINTN        RootCertLength,
+  IN CONST UINT8  *CertChain,
+  IN UINTN        CertChainLength
+  )
+{
+  CONST UINT8  *TmpPtr;
+  UINTN        Length;
+  UINT32       Asn1Tag;
+  UINT32       ObjClass;
+  CONST UINT8  *CurrentCert;
+  UINTN        CurrentCertLen;
+  CONST UINT8  *PrecedingCert;
+  UINTN        PrecedingCertLen;
+  BOOLEAN      VerifyFlag;
+  INT32        Ret;
+
+  PrecedingCert    = RootCert;
+  PrecedingCertLen = RootCertLength;
+
+  CurrentCert    = CertChain;
+  Length         = 0;
+  CurrentCertLen = 0;
+
+  VerifyFlag = FALSE;
+  while (TRUE) {
+    TmpPtr = CurrentCert;
+    Ret    = ASN1_get_object (
+               (CONST UINT8 **)&TmpPtr,
+               (long *)&Length,
+               (int *)&Asn1Tag,
+               (int *)&ObjClass,
+               (long)(CertChainLength + CertChain - TmpPtr)
+               );
+    if ((Asn1Tag != V_ASN1_SEQUENCE) || (Ret == 0x80)) {
+      break;
+    }
+
+    //
+    // Calculate CurrentCert length;
+    //
+    CurrentCertLen = TmpPtr - CurrentCert + Length;
+
+    //
+    // Verify CurrentCert with preceding cert;
+    //
+    VerifyFlag = X509VerifyCert (CurrentCert, CurrentCertLen, PrecedingCert, PrecedingCertLen);
+    if (VerifyFlag == FALSE) {
+      break;
+    }
+
+    //
+    // move Current cert to Preceding cert
+    //
+    PrecedingCertLen = CurrentCertLen;
+    PrecedingCert    = CurrentCert;
+
+    //
+    // Move to next
+    //
+    CurrentCert = CurrentCert + CurrentCertLen;
+  }
+
+  return VerifyFlag;
+}
+
+/**
+  Get one X509 certificate from CertChain.
+
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @param[in]      CertIndex         Index of certificate.
+
+  @param[out]     Cert              The certificate at the index of CertChain.
+  @param[out]     CertLength        The length certificate at the index of CertChain.
+
+  @retval  TRUE   Success.
+  @retval  FALSE  Failed to get certificate from certificate chain.
+**/
+BOOLEAN
+EFIAPI
+X509GetCertFromCertChain (
+  IN CONST UINT8   *CertChain,
+  IN UINTN         CertChainLength,
+  IN CONST INT32   CertIndex,
+  OUT CONST UINT8  **Cert,
+  OUT UINTN        *CertLength
+  )
+{
+  UINTN        Asn1Len;
+  INT32        CurrentIndex;
+  UINTN        CurrentCertLen;
+  CONST UINT8  *CurrentCert;
+  CONST UINT8  *TmpPtr;
+  INT32        Ret;
+  UINT32       Asn1Tag;
+  UINT32       ObjClass;
+
+  //
+  // Check input parameters.
+  //
+  if ((CertChain == NULL) || (Cert == NULL) ||
+      (CertIndex < -1) || (CertLength == NULL))
+  {
+    return FALSE;
+  }
+
+  Asn1Len        = 0;
+  CurrentCertLen = 0;
+  CurrentCert    = CertChain;
+  CurrentIndex   = -1;
+
+  //
+  // Traverse the certificate chain
+  //
+  while (TRUE) {
+    TmpPtr = CurrentCert;
+
+    // Get asn1 object and taglen
+    Ret = ASN1_get_object (
+            (CONST UINT8 **)&TmpPtr,
+            (long *)&Asn1Len,
+            (int *)&Asn1Tag,
+            (int *)&ObjClass,
+            (long)(CertChainLength + CertChain - TmpPtr)
+            );
+    if ((Asn1Tag != V_ASN1_SEQUENCE) || (Ret == 0x80)) {
+      break;
+    }
+
+    //
+    // Calculate CurrentCert length;
+    //
+    CurrentCertLen = TmpPtr - CurrentCert + Asn1Len;
+    CurrentIndex++;
+
+    if (CurrentIndex == CertIndex) {
+      *Cert       = CurrentCert;
+      *CertLength = CurrentCertLen;
+      return TRUE;
+    }
+
+    //
+    // Move to next
+    //
+    CurrentCert = CurrentCert + CurrentCertLen;
+  }
+
+  //
+  // If CertIndex is -1, Return the last certificate
+  //
+  if ((CertIndex == -1) && (CurrentIndex >= 0)) {
+    *Cert       = CurrentCert - CurrentCertLen;
+    *CertLength = CurrentCertLen;
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/**
+  Retrieve the tag and length of the tag.
+
+  @param Ptr      The position in the ASN.1 data
+  @param End      End of data
+  @param Length   The variable that will receive the length
+  @param Tag      The expected tag
+
+  @retval      TRUE   Get tag successful
+  @retval      FALSe  Failed to get tag or tag not match
+**/
+BOOLEAN
+EFIAPI
+Asn1GetTag (
+  IN OUT UINT8   **Ptr,
+  IN     UINT8   *End,
+  OUT UINTN      *Length,
+  IN     UINT32  Tag
+  )
+{
+  UINT8  *PtrOld;
+  INT32  ObjTag;
+  INT32  ObjCls;
+  long   ObjLength;
+
+  //
+  // Save Ptr position
+  //
+  PtrOld = *Ptr;
+
+  ASN1_get_object ((CONST UINT8 **)Ptr, &ObjLength, &ObjTag, &ObjCls, (INT32)(End - (*Ptr)));
+  if ((ObjTag == (INT32)(Tag & CRYPTO_ASN1_TAG_VALUE_MASK)) &&
+      (ObjCls == (INT32)(Tag & CRYPTO_ASN1_TAG_CLASS_MASK)))
+  {
+    *Length = (UINTN)ObjLength;
+    return TRUE;
+  } else {
+    //
+    // if doesn't match Tag, restore Ptr to origin Ptr
+    //
+    *Ptr = PtrOld;
+    return FALSE;
+  }
+}
+
+/**
+  Retrieve the basic constraints from one X.509 certificate.
+
+  @param[in]      Cert                     Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize                 size of the X509 certificate in bytes.
+  @param[out]     BasicConstraints         basic constraints bytes.
+  @param[in, out] BasicConstraintsSize     basic constraints buffer sizs in bytes.
+
+  @retval TRUE                     The basic constraints retrieve successfully.
+  @retval FALSE                    If cert is NULL.
+                                   If cert_size is NULL.
+                                   If basic_constraints is not NULL and *basic_constraints_size is 0.
+                                   If cert is invalid.
+  @retval FALSE                    The required buffer size is small.
+                                   The return buffer size is basic_constraints_size parameter.
+  @retval FALSE                    If no Extension entry match oid.
+  @retval FALSE                    The operation is not supported.
+ **/
+BOOLEAN
+EFIAPI
+X509GetExtendedBasicConstraints             (
+  CONST UINT8  *Cert,
+  UINTN        CertSize,
+  UINT8        *BasicConstraints,
+  UINTN        *BasicConstraintsSize
+  )
+{
+  BOOLEAN  Status;
+
+  if ((Cert == NULL) || (CertSize == 0) || (BasicConstraintsSize == NULL)) {
+    return FALSE;
+  }
+
+  Status = X509GetExtensionData (
+             (UINT8 *)Cert,
+             CertSize,
+             mOidBasicConstraints,
+             sizeof (mOidBasicConstraints),
+             BasicConstraints,
+             BasicConstraintsSize
+             );
+
+  return Status;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509Null.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509Null.c
index 38819723c7..bd2a12fc14 100644
--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509Null.c
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509Null.c
@@ -292,3 +292,432 @@ X509GetTBSCert (
   ASSERT (FALSE);
   return FALSE;
 }
+
+/**
+  Retrieve the version from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     Version      Pointer to the retrieved version integer.
+
+  @retval TRUE           The certificate version retrieved successfully.
+  @retval FALSE          If  Cert is NULL or CertSize is Zero.
+  @retval FALSE          The operation is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetVersion (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINTN        *Version
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the serialNumber from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     SerialNumber  Pointer to the retrieved certificate SerialNumber bytes.
+  @param[in, out] SerialNumberSize  The size in bytes of the SerialNumber buffer on input,
+                               and the size of buffer returned SerialNumber on output.
+
+  @retval TRUE                     The certificate serialNumber retrieved successfully.
+  @retval FALSE                    If Cert is NULL or CertSize is Zero.
+                                   If SerialNumberSize is NULL.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SerialNumber exists.
+  @retval FALSE                    If the SerialNumber is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   SerialNumberSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSerialNumber (
+  IN      CONST UINT8 *Cert,
+  IN      UINTN CertSize,
+  OUT     UINT8 *SerialNumber, OPTIONAL
+  IN OUT  UINTN         *SerialNumberSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the issuer bytes from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     CertIssuer  Pointer to the retrieved certificate subject bytes.
+  @param[in, out] CertIssuerSize  The size in bytes of the CertIssuer buffer on input,
+                               and the size of buffer returned CertSubject on output.
+
+  @retval  TRUE   The certificate issuer retrieved successfully.
+  @retval  FALSE  Invalid certificate, or the CertIssuerSize is too small for the result.
+                  The CertIssuerSize will be updated with the required size.
+  @retval  FALSE  This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetIssuerName (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINT8        *CertIssuer,
+  IN OUT  UINTN        *CertIssuerSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the Signature Algorithm from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Oid              Signature Algorithm Object identifier buffer.
+  @param[in,out]  OidSize          Signature Algorithm Object identifier buffer size
+
+  @retval TRUE           The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If OidSize is NULL.
+                                   If Oid is not NULL and *OidSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SignatureType.
+  @retval FALSE                    If the Oid is NULL. The required buffer size
+                                   is returned in the OidSize.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSignatureAlgorithm (
+  IN CONST UINT8 *Cert,
+  IN       UINTN CertSize,
+  OUT   UINT8 *Oid, OPTIONAL
+  IN OUT   UINTN       *OidSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve Extension data from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[in]      Oid              Object identifier buffer
+  @param[in]      OidSize          Object identifier buffer size
+  @param[out]     ExtensionData    Extension bytes.
+  @param[in, out] ExtensionDataSize Extension bytes size.
+
+  @retval TRUE                     The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If ExtensionDataSize is NULL.
+                                   If ExtensionData is not NULL and *ExtensionDataSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no Extension entry match Oid.
+  @retval FALSE                    If the ExtensionData is NULL. The required buffer size
+                                   is returned in the ExtensionDataSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtensionData (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     CONST UINT8  *Oid,
+  IN     UINTN        OidSize,
+  OUT UINT8           *ExtensionData,
+  IN OUT UINTN        *ExtensionDataSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the Extended Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage bytes.
+  @param[in, out] UsageSize        Key Usage buffer sizs in bytes.
+
+  @retval TRUE                     The Usage bytes retrieve successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If CertSize is NULL.
+                                   If Usage is not NULL and *UsageSize is 0.
+                                   If Cert is invalid.
+  @retval FALSE                    If the Usage is NULL. The required buffer size
+                                   is returned in the UsageSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtendedKeyUsage (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  OUT UINT8           *Usage,
+  IN OUT UINTN        *UsageSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the Validity from one X.509 certificate
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[in]      From         notBefore Pointer to DateTime object.
+  @param[in,out]  FromSize     notBefore DateTime object size.
+  @param[in]     To           notAfter Pointer to DateTime object.
+  @param[in,out]  ToSize       notAfter DateTime object size.
+
+  Note: X509CompareDateTime to compare DateTime oject
+        x509SetDateTime to get a DateTime object from a DateTimeStr
+
+  @retval  TRUE   The certificate Validity retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Validity retrieve failed.
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetValidity  (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     UINT8        *From,
+  IN OUT UINTN        *FromSize,
+  IN     UINT8        *To,
+  IN OUT UINTN        *ToSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Format a DateTime object into DataTime Buffer
+
+  If DateTimeStr is NULL, then return FALSE.
+  If DateTimeSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      DateTimeStr      DateTime string like YYYYMMDDhhmmssZ
+                                   Ref: https://www.w3.org/TR/NOTE-datetime
+                                   Z stand for UTC time
+  @param[out]     DateTime         Pointer to a DateTime object.
+  @param[in,out]  DateTimeSize     DateTime object buffer size.
+
+  @retval TRUE                     The DateTime object create successfully.
+  @retval FALSE                    If DateTimeStr is NULL.
+                                   If DateTimeSize is NULL.
+                                   If DateTime is not NULL and *DateTimeSize is 0.
+                                   If Year Month Day Hour Minute Second combination is invalid datetime.
+  @retval FALSE                    If the DateTime is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   DateTimeSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509SetDateTime (
+  IN     CHAR8  *DateTimeStr,
+  OUT VOID      *DateTime,
+  IN OUT UINTN  *DateTimeSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Compare DateTime1 object and DateTime2 object.
+
+  If DateTime1 is NULL, then return -2.
+  If DateTime2 is NULL, then return -2.
+  If DateTime1 == DateTime2, then return 0
+  If DateTime1 > DateTime2, then return 1
+  If DateTime1 < DateTime2, then return -1
+
+  @param[in]      DateTime1         Pointer to a DateTime Ojbect
+  @param[in]      DateTime2         Pointer to a DateTime Object
+
+  @retval  0      If DateTime1 == DateTime2
+  @retval  1      If DateTime1 > DateTime2
+  @retval  -1     If DateTime1 < DateTime2
+**/
+INT32
+EFIAPI
+X509CompareDateTime (
+  IN  CONST  VOID  *DateTime1,
+  IN  CONST  VOID  *DateTime2
+  )
+{
+  ASSERT (FALSE);
+  return -3;
+}
+
+/**
+  Retrieve the Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage (CRYPTO_X509_KU_*)
+
+  @retval  TRUE   The certificate Key Usage retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Usage is NULL
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetKeyUsage (
+  IN    CONST UINT8  *Cert,
+  IN    UINTN        CertSize,
+  OUT   UINTN        *Usage
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Verify one X509 certificate was issued by the trusted CA.
+  @param[in]      RootCert          Trusted Root Certificate buffer
+
+  @param[in]      RootCertLength    Trusted Root Certificate buffer length
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @retval  TRUE   All cerificates was issued by the first certificate in X509Certchain.
+  @retval  FALSE  Invalid certificate or the certificate was not issued by the given
+                  trusted CA.
+**/
+BOOLEAN
+EFIAPI
+X509VerifyCertChain (
+  IN CONST UINT8  *RootCert,
+  IN UINTN        RootCertLength,
+  IN CONST UINT8  *CertChain,
+  IN UINTN        CertChainLength
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Get one X509 certificate from CertChain.
+
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @param[in]      CertIndex         Index of certificate.
+
+  @param[out]     Cert              The certificate at the index of CertChain.
+  @param[out]     CertLength        The length certificate at the index of CertChain.
+
+  @retval  TRUE   Success.
+  @retval  FALSE  Failed to get certificate from certificate chain.
+**/
+BOOLEAN
+EFIAPI
+X509GetCertFromCertChain (
+  IN CONST UINT8   *CertChain,
+  IN UINTN         CertChainLength,
+  IN CONST INT32   CertIndex,
+  OUT CONST UINT8  **Cert,
+  OUT UINTN        *CertLength
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the tag and length of the tag.
+
+  @param Ptr      The position in the ASN.1 data
+  @param End      End of data
+  @param Length   The variable that will receive the length
+  @param Tag      The expected tag
+
+  @retval      TRUE   Get tag successful
+  @retval      FALSe  Failed to get tag or tag not match
+**/
+BOOLEAN
+EFIAPI
+Asn1GetTag (
+  IN OUT UINT8   **Ptr,
+  IN     UINT8   *End,
+  OUT UINTN      *Length,
+  IN     UINT32  Tag
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the basic constraints from one X.509 certificate.
+
+  @param[in]      Cert                     Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize                 size of the X509 certificate in bytes.
+  @param[out]     BasicConstraints         basic constraints bytes.
+  @param[in, out] BasicConstraintsSize     basic constraints buffer sizs in bytes.
+
+  @retval TRUE                     The basic constraints retrieve successfully.
+  @retval FALSE                    If cert is NULL.
+                                   If cert_size is NULL.
+                                   If basic_constraints is not NULL and *basic_constraints_size is 0.
+                                   If cert is invalid.
+  @retval FALSE                    The required buffer size is small.
+                                   The return buffer size is basic_constraints_size parameter.
+  @retval FALSE                    If no Extension entry match oid.
+  @retval FALSE                    The operation is not supported.
+ **/
+BOOLEAN
+EFIAPI
+X509GetExtendedBasicConstraints             (
+  CONST UINT8  *Cert,
+  UINTN        CertSize,
+  UINT8        *BasicConstraints,
+  UINTN        *BasicConstraintsSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptX509Null.c b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptX509Null.c
index 38819723c7..0068f00738 100644
--- a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptX509Null.c
+++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptX509Null.c
@@ -292,3 +292,432 @@ X509GetTBSCert (
   ASSERT (FALSE);
   return FALSE;
 }
+
+/**
+  Retrieve the version from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     Version      Pointer to the retrieved version integer.
+
+  @retval TRUE           The certificate version retrieved successfully.
+  @retval FALSE          If  Cert is NULL or CertSize is Zero.
+  @retval FALSE          The operation is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetVersion (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINTN        *Version
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the serialNumber from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     SerialNumber  Pointer to the retrieved certificate SerialNumber bytes.
+  @param[in, out] SerialNumberSize  The size in bytes of the SerialNumber buffer on input,
+                               and the size of buffer returned SerialNumber on output.
+
+  @retval TRUE                     The certificate serialNumber retrieved successfully.
+  @retval FALSE                    If Cert is NULL or CertSize is Zero.
+                                   If SerialNumberSize is NULL.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SerialNumber exists.
+  @retval FALSE                    If the SerialNumber is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   SerialNumberSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSerialNumber (
+  IN      CONST UINT8 *Cert,
+  IN      UINTN CertSize,
+  OUT     UINT8 *SerialNumber, OPTIONAL
+  IN OUT  UINTN         *SerialNumberSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the issuer bytes from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     CertIssuer  Pointer to the retrieved certificate subject bytes.
+  @param[in, out] CertIssuerSize  The size in bytes of the CertIssuer buffer on input,
+                               and the size of buffer returned CertSubject on output.
+
+  @retval  TRUE   The certificate issuer retrieved successfully.
+  @retval  FALSE  Invalid certificate, or the CertIssuerSize is too small for the result.
+                  The CertIssuerSize will be updated with the required size.
+  @retval  FALSE  This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetIssuerName (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINT8        *CertIssuer,
+  IN OUT  UINTN        *CertIssuerSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the Signature Algorithm from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Oid              Signature Algorithm Object identifier buffer.
+  @param[in,out]  OidSize          Signature Algorithm Object identifier buffer size
+
+  @retval TRUE           The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If OidSize is NULL.
+                                   If Oid is not NULL and *OidSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SignatureType.
+  @retval FALSE                    If the Oid is NULL. The required buffer size
+                                   is returned in the OidSize.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSignatureAlgorithm (
+  IN CONST UINT8 *Cert,
+  IN       UINTN CertSize,
+  OUT   UINT8 *Oid, OPTIONAL
+  IN OUT   UINTN       *OidSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve Extension data from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[in]      Oid              Object identifier buffer
+  @param[in]      OidSize          Object identifier buffer size
+  @param[out]     ExtensionData    Extension bytes.
+  @param[in, out] ExtensionDataSize Extension bytes size.
+
+  @retval TRUE                     The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If ExtensionDataSize is NULL.
+                                   If ExtensionData is not NULL and *ExtensionDataSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no Extension entry match Oid.
+  @retval FALSE                    If the ExtensionData is NULL. The required buffer size
+                                   is returned in the ExtensionDataSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtensionData (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     CONST UINT8  *Oid,
+  IN     UINTN        OidSize,
+  OUT UINT8           *ExtensionData,
+  IN OUT UINTN        *ExtensionDataSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the Extended Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage bytes.
+  @param[in, out] UsageSize        Key Usage buffer sizs in bytes.
+
+  @retval TRUE                     The Usage bytes retrieve successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If CertSize is NULL.
+                                   If Usage is not NULL and *UsageSize is 0.
+                                   If Cert is invalid.
+  @retval FALSE                    If the Usage is NULL. The required buffer size
+                                   is returned in the UsageSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtendedKeyUsage (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  OUT UINT8           *Usage,
+  IN OUT UINTN        *UsageSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the Validity from one X.509 certificate
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[in]      From         notBefore Pointer to DateTime object.
+  @param[in,out]  FromSize     notBefore DateTime object size.
+  @param[in]     To           notAfter Pointer to DateTime object.
+  @param[in,out]  ToSize       notAfter DateTime object size.
+
+  Note: X509CompareDateTime to compare DateTime oject
+        x509SetDateTime to get a DateTime object from a DateTimeStr
+
+  @retval  TRUE   The certificate Validity retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Validity retrieve failed.
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetValidity  (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     UINT8        *From,
+  IN OUT UINTN        *FromSize,
+  IN     UINT8        *To,
+  IN OUT UINTN        *ToSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Format a DateTime object into DataTime Buffer
+
+  If DateTimeStr is NULL, then return FALSE.
+  If DateTimeSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      DateTimeStr      DateTime string like YYYYMMDDhhmmssZ
+                                   Ref: https://www.w3.org/TR/NOTE-datetime
+                                   Z stand for UTC time
+  @param[out]     DateTime         Pointer to a DateTime object.
+  @param[in,out]  DateTimeSize     DateTime object buffer size.
+
+  @retval TRUE                     The DateTime object create successfully.
+  @retval FALSE                    If DateTimeStr is NULL.
+                                   If DateTimeSize is NULL.
+                                   If DateTime is not NULL and *DateTimeSize is 0.
+                                   If Year Month Day Hour Minute Second combination is invalid datetime.
+  @retval FALSE                    If the DateTime is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   DateTimeSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509SetDateTime (
+  IN     CHAR8  *DateTimeStr,
+  OUT VOID      *DateTime,
+  IN OUT UINTN  *DateTimeSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Compare DateTime1 object and DateTime2 object.
+
+  If DateTime1 is NULL, then return -2.
+  If DateTime2 is NULL, then return -2.
+  If DateTime1 == DateTime2, then return 0
+  If DateTime1 > DateTime2, then return 1
+  If DateTime1 < DateTime2, then return -1
+
+  @param[in]      DateTime1         Pointer to a DateTime Ojbect
+  @param[in]      DateTime2         Pointer to a DateTime Object
+
+  @retval  0      If DateTime1 == DateTime2
+  @retval  1      If DateTime1 > DateTime2
+  @retval  -1     If DateTime1 < DateTime2
+**/
+INT32
+EFIAPI
+X509CompareDateTime (
+  IN CONST  VOID  *DateTime1,
+  IN CONST  VOID  *DateTime2
+  )
+{
+  ASSERT (FALSE);
+  return -3;
+}
+
+/**
+  Retrieve the Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage (CRYPTO_X509_KU_*)
+
+  @retval  TRUE   The certificate Key Usage retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Usage is NULL
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetKeyUsage (
+  IN    CONST UINT8  *Cert,
+  IN    UINTN        CertSize,
+  OUT   UINTN        *Usage
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Verify one X509 certificate was issued by the trusted CA.
+  @param[in]      RootCert          Trusted Root Certificate buffer
+
+  @param[in]      RootCertLength    Trusted Root Certificate buffer length
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @retval  TRUE   All cerificates was issued by the first certificate in X509Certchain.
+  @retval  FALSE  Invalid certificate or the certificate was not issued by the given
+                  trusted CA.
+**/
+BOOLEAN
+EFIAPI
+X509VerifyCertChain (
+  IN CONST UINT8  *RootCert,
+  IN UINTN        RootCertLength,
+  IN CONST UINT8  *CertChain,
+  IN UINTN        CertChainLength
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Get one X509 certificate from CertChain.
+
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @param[in]      CertIndex         Index of certificate.
+
+  @param[out]     Cert              The certificate at the index of CertChain.
+  @param[out]     CertLength        The length certificate at the index of CertChain.
+
+  @retval  TRUE   Success.
+  @retval  FALSE  Failed to get certificate from certificate chain.
+**/
+BOOLEAN
+EFIAPI
+X509GetCertFromCertChain (
+  IN CONST UINT8   *CertChain,
+  IN UINTN         CertChainLength,
+  IN CONST INT32   CertIndex,
+  OUT CONST UINT8  **Cert,
+  OUT UINTN        *CertLength
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the tag and length of the tag.
+
+  @param Ptr      The position in the ASN.1 data
+  @param End      End of data
+  @param Length   The variable that will receive the length
+  @param Tag      The expected tag
+
+  @retval      TRUE   Get tag successful
+  @retval      FALSe  Failed to get tag or tag not match
+**/
+BOOLEAN
+EFIAPI
+Asn1GetTag (
+  IN OUT UINT8   **Ptr,
+  IN     UINT8   *End,
+  OUT UINTN      *Length,
+  IN     UINT32  Tag
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the basic constraints from one X.509 certificate.
+
+  @param[in]      Cert                     Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize                 size of the X509 certificate in bytes.
+  @param[out]     BasicConstraints         basic constraints bytes.
+  @param[in, out] BasicConstraintsSize     basic constraints buffer sizs in bytes.
+
+  @retval TRUE                     The basic constraints retrieve successfully.
+  @retval FALSE                    If cert is NULL.
+                                   If cert_size is NULL.
+                                   If basic_constraints is not NULL and *basic_constraints_size is 0.
+                                   If cert is invalid.
+  @retval FALSE                    The required buffer size is small.
+                                   The return buffer size is basic_constraints_size parameter.
+  @retval FALSE                    If no Extension entry match oid.
+  @retval FALSE                    The operation is not supported.
+ **/
+BOOLEAN
+EFIAPI
+X509GetExtendedBasicConstraints             (
+  CONST UINT8  *Cert,
+  UINTN        CertSize,
+  UINT8        *BasicConstraints,
+  UINTN        *BasicConstraintsSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
-- 
2.26.2.windows.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/4] CryptoPkg: add new X509 function to Crypto Service.
  2022-09-25  8:54 [PATCH 0/4] CryptoPkg: add more X509 functions Qi Zhang
  2022-09-25  8:54 ` [PATCH 1/4] CryptoPkg: add new X509 function definition Qi Zhang
  2022-09-25  8:54 ` [PATCH 2/4] CryptoPkg: add new X509 function Qi Zhang
@ 2022-09-25  8:54 ` Qi Zhang
  2022-09-25  8:54 ` [PATCH 4/4] CryptoPkg: add Unit Test for X509 new function Qi Zhang
  3 siblings, 0 replies; 7+ messages in thread
From: Qi Zhang @ 2022-09-25  8:54 UTC (permalink / raw)
  To: devel; +Cc: Qi Zhang, Jiewen Yao, Jian J Wang, Xiaoyu Lu, Guomin Jiang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4082

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Signed-off-by: Qi Zhang <qi1.zhang@intel.com>
---
 CryptoPkg/Driver/Crypto.c                     | 430 ++++++++++
 .../Pcd/PcdCryptoServiceFamilyEnable.h        |  34 +-
 .../BaseCryptLibOnProtocolPpi/CryptLib.c      | 415 +++++++++
 CryptoPkg/Private/Protocol/Crypto.h           | 790 +++++++++++++-----
 4 files changed, 1459 insertions(+), 210 deletions(-)

diff --git a/CryptoPkg/Driver/Crypto.c b/CryptoPkg/Driver/Crypto.c
index 9872b5bf70..343d73b9db 100644
--- a/CryptoPkg/Driver/Crypto.c
+++ b/CryptoPkg/Driver/Crypto.c
@@ -3086,6 +3086,421 @@ CryptoServiceX509GetTBSCert (
   return CALL_BASECRYPTLIB (X509.Services.GetTBSCert, X509GetTBSCert, (Cert, CertSize, TBSCert, TBSCertSize), FALSE);
 }
 
+/**
+  Retrieve the version from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     Version      Pointer to the retrieved version integer.
+
+  @retval TRUE           The certificate version retrieved successfully.
+  @retval FALSE          If  Cert is NULL or CertSize is Zero.
+  @retval FALSE          The operation is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetVersion (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINTN        *Version
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetVersion, X509GetVersion, (Cert, CertSize, Version), FALSE);
+}
+
+/**
+  Retrieve the serialNumber from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     SerialNumber  Pointer to the retrieved certificate SerialNumber bytes.
+  @param[in, out] SerialNumberSize  The size in bytes of the SerialNumber buffer on input,
+                               and the size of buffer returned SerialNumber on output.
+
+  @retval TRUE                     The certificate serialNumber retrieved successfully.
+  @retval FALSE                    If Cert is NULL or CertSize is Zero.
+                                   If SerialNumberSize is NULL.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SerialNumber exists.
+  @retval FALSE                    If the SerialNumber is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   SerialNumberSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetSerialNumber (
+  IN      CONST UINT8 *Cert,
+  IN      UINTN CertSize,
+  OUT     UINT8 *SerialNumber, OPTIONAL
+  IN OUT  UINTN         *SerialNumberSize
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetSerialNumber, X509GetSerialNumber, (Cert, CertSize, SerialNumber, SerialNumberSize), FALSE);
+}
+
+/**
+  Retrieve the issuer bytes from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     CertIssuer  Pointer to the retrieved certificate subject bytes.
+  @param[in, out] CertIssuerSize  The size in bytes of the CertIssuer buffer on input,
+                               and the size of buffer returned CertSubject on output.
+
+  @retval  TRUE   The certificate issuer retrieved successfully.
+  @retval  FALSE  Invalid certificate, or the CertIssuerSize is too small for the result.
+                  The CertIssuerSize will be updated with the required size.
+  @retval  FALSE  This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetIssuerName (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINT8        *CertIssuer,
+  IN OUT  UINTN        *CertIssuerSize
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetIssuerName, X509GetIssuerName, (Cert, CertSize, CertIssuer, CertIssuerSize), FALSE);
+}
+
+/**
+  Retrieve the Signature Algorithm from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Oid              Signature Algorithm Object identifier buffer.
+  @param[in,out]  OidSize          Signature Algorithm Object identifier buffer size
+
+  @retval TRUE                     The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If OidSize is NULL.
+                                   If Oid is not NULL and *OidSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SignatureType.
+  @retval FALSE                    If the Oid is NULL. The required buffer size
+                                   is returned in the OidSize.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetSignatureAlgorithm (
+  IN CONST UINT8 *Cert,
+  IN       UINTN CertSize,
+  OUT   UINT8 *Oid, OPTIONAL
+  IN OUT   UINTN       *OidSize
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetSignatureAlgorithm, X509GetSignatureAlgorithm, (Cert, CertSize, Oid, OidSize), FALSE);
+}
+
+/**
+  Retrieve Extension data from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[in]      Oid              Object identifier buffer
+  @param[in]      OidSize          Object identifier buffer size
+  @param[out]     ExtensionData    Extension bytes.
+  @param[in, out] ExtensionDataSize Extension bytes size.
+
+  @retval TRUE                     The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If ExtensionDataSize is NULL.
+                                   If ExtensionData is not NULL and *ExtensionDataSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no Extension entry match Oid.
+  @retval FALSE                    If the ExtensionData is NULL. The required buffer size
+                                   is returned in the ExtensionDataSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetExtensionData (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     CONST UINT8  *Oid,
+  IN     UINTN        OidSize,
+  OUT UINT8           *ExtensionData,
+  IN OUT UINTN        *ExtensionDataSize
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetExtensionData, X509GetExtensionData, (Cert, CertSize, Oid, OidSize, ExtensionData, ExtensionDataSize), FALSE);
+}
+
+/**
+  Retrieve the Extended Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage bytes.
+  @param[in, out] UsageSize        Key Usage buffer sizs in bytes.
+
+  @retval TRUE                     The Usage bytes retrieve successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If CertSize is NULL.
+                                   If Usage is not NULL and *UsageSize is 0.
+                                   If Cert is invalid.
+  @retval FALSE                    If the Usage is NULL. The required buffer size
+                                   is returned in the UsageSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetExtendedKeyUsage (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  OUT UINT8           *Usage,
+  IN OUT UINTN        *UsageSize
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetExtendedKeyUsage, X509GetExtendedKeyUsage, (Cert, CertSize, Usage, UsageSize), FALSE);
+}
+
+/**
+  Retrieve the Validity from one X.509 certificate
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[in]      From         notBefore Pointer to DateTime object.
+  @param[in,out]  FromSize     notBefore DateTime object size.
+  @param[in]      To           notAfter Pointer to DateTime object.
+  @param[in,out]  ToSize       notAfter DateTime object size.
+
+  Note: X509CompareDateTime to compare DateTime oject
+        x509SetDateTime to get a DateTime object from a DateTimeStr
+
+  @retval  TRUE   The certificate Validity retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Validity retrieve failed.
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetValidity  (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     UINT8        *From,
+  IN OUT UINTN        *FromSize,
+  IN     UINT8        *To,
+  IN OUT UINTN        *ToSize
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetValidity, X509GetValidity, (Cert, CertSize, From, FromSize, To, ToSize), FALSE);
+}
+
+/**
+  Format a DateTime object into DataTime Buffer
+
+  If DateTimeStr is NULL, then return FALSE.
+  If DateTimeSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      DateTimeStr      DateTime string like YYYYMMDDhhmmssZ
+                                   Ref: https://www.w3.org/TR/NOTE-datetime
+                                   Z stand for UTC time
+  @param[out]     DateTime         Pointer to a DateTime object.
+  @param[in,out]  DateTimeSize     DateTime object buffer size.
+
+  @retval TRUE                     The DateTime object create successfully.
+  @retval FALSE                    If DateTimeStr is NULL.
+                                   If DateTimeSize is NULL.
+                                   If DateTime is not NULL and *DateTimeSize is 0.
+                                   If Year Month Day Hour Minute Second combination is invalid datetime.
+  @retval FALSE                    If the DateTime is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   DateTimeSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509SetDateTime (
+  IN     CHAR8  *DateTimeStr,
+  OUT VOID      *DateTime,
+  IN OUT UINTN  *DateTimeSize
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.SetDateTime, X509SetDateTime, (DateTimeStr, DateTime, DateTimeSize), FALSE);
+}
+
+/**
+  Compare DateTime1 object and DateTime2 object.
+
+  If DateTime1 is NULL, then return -2.
+  If DateTime2 is NULL, then return -2.
+  If DateTime1 == DateTime2, then return 0
+  If DateTime1 > DateTime2, then return 1
+  If DateTime1 < DateTime2, then return -1
+
+  @param[in]      DateTime1         Pointer to a DateTime Ojbect
+  @param[in]      DateTime2         Pointer to a DateTime Object
+
+  @retval  0      If DateTime1 == DateTime2
+  @retval  1      If DateTime1 > DateTime2
+  @retval  -1     If DateTime1 < DateTime2
+**/
+INT32
+EFIAPI
+CryptoServiceX509CompareDateTime (
+  IN  CONST VOID  *DateTime1,
+  IN  CONST VOID  *DateTime2
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.CompareDateTime, X509CompareDateTime, (DateTime1, DateTime2), FALSE);
+}
+
+/**
+  Retrieve the Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage (CRYPTO_X509_KU_*)
+
+  @retval  TRUE   The certificate Key Usage retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Usage is NULL
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetKeyUsage (
+  IN    CONST UINT8  *Cert,
+  IN    UINTN        CertSize,
+  OUT   UINTN        *Usage
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetKeyUsage, X509GetKeyUsage, (Cert, CertSize, Usage), FALSE);
+}
+
+/**
+  Verify one X509 certificate was issued by the trusted CA.
+  @param[in]      RootCert          Trusted Root Certificate buffer
+
+  @param[in]      RootCertLength    Trusted Root Certificate buffer length
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @retval  TRUE   All cerificates was issued by the first certificate in X509Certchain.
+  @retval  FALSE  Invalid certificate or the certificate was not issued by the given
+                  trusted CA.
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509VerifyCertChain (
+  IN CONST UINT8  *RootCert,
+  IN UINTN        RootCertLength,
+  IN CONST UINT8  *CertChain,
+  IN UINTN        CertChainLength
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.VerifyCertChain, X509VerifyCertChain, (RootCert, RootCertLength, CertChain, CertChainLength), FALSE);
+}
+
+/**
+  Get one X509 certificate from CertChain.
+
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @param[in]      CertIndex         Index of certificate.
+
+  @param[out]     Cert              The certificate at the index of CertChain.
+  @param[out]     CertLength        The length certificate at the index of CertChain.
+
+  @retval  TRUE   Success.
+  @retval  FALSE  Failed to get certificate from certificate chain.
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetCertFromCertChain (
+  IN CONST UINT8   *CertChain,
+  IN UINTN         CertChainLength,
+  IN CONST INT32   CertIndex,
+  OUT CONST UINT8  **Cert,
+  OUT UINTN        *CertLength
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetCertFromCertChain, X509GetCertFromCertChain, (CertChain, CertChainLength, CertIndex, Cert, CertLength), FALSE);
+}
+
+/**
+  Retrieve the tag and length of the tag.
+
+  @param Ptr      The position in the ASN.1 data
+  @param End      End of data
+  @param Length   The variable that will receive the length
+  @param Tag      The expected tag
+
+  @retval      TRUE   Get tag successful
+  @retval      FALSe  Failed to get tag or tag not match
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceAsn1GetTag (
+  IN OUT UINT8   **Ptr,
+  IN     UINT8   *End,
+  OUT UINTN      *Length,
+  IN     UINT32  Tag
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.Asn1GetTag, Asn1GetTag, (Ptr, End, Length, Tag), FALSE);
+}
+
+/**
+  Retrieve the basic constraints from one X.509 certificate.
+
+  @param[in]      Cert                     Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize                 size of the X509 certificate in bytes.
+  @param[out]     BasicConstraints         basic constraints bytes.
+  @param[in, out] BasicConstraintsSize     basic constraints buffer sizs in bytes.
+
+  @retval TRUE                     The basic constraints retrieve successfully.
+  @retval FALSE                    If cert is NULL.
+                                   If cert_size is NULL.
+                                   If basic_constraints is not NULL and *basic_constraints_size is 0.
+                                   If cert is invalid.
+  @retval FALSE                    The required buffer size is small.
+                                   The return buffer size is basic_constraints_size parameter.
+  @retval FALSE                    If no Extension entry match oid.
+  @retval FALSE                    The operation is not supported.
+ **/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetExtendedBasicConstraints             (
+  CONST UINT8  *Cert,
+  UINTN        CertSize,
+  UINT8        *BasicConstraints,
+  UINTN        *BasicConstraintsSize
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetExtendedBasicConstraints, X509GetExtendedBasicConstraints, (Cert, CertSize, BasicConstraints, BasicConstraintsSize), FALSE);
+}
+
 /**
   Derives a key from a password using a salt and iteration count, based on PKCS#5 v2.0
   password based encryption key derivation function PBKDF2, as specified in RFC 2898.
@@ -5770,4 +6185,19 @@ const EDKII_CRYPTO_PROTOCOL  mEdkiiCrypto = {
   CryptoServiceBigNumContextFree,
   CryptoServiceBigNumSetUint,
   CryptoServiceBigNumAddMod,
+  /// X509 (Continued)
+  CryptoServiceX509GetVersion,
+  CryptoServiceX509GetSerialNumber,
+  CryptoServiceX509GetIssuerName,
+  CryptoServiceX509GetSignatureAlgorithm,
+  CryptoServiceX509GetExtensionData,
+  CryptoServiceX509GetExtendedKeyUsage,
+  CryptoServiceX509GetValidity,
+  CryptoServiceX509SetDateTime,
+  CryptoServiceX509CompareDateTime,
+  CryptoServiceX509GetKeyUsage,
+  CryptoServiceX509VerifyCertChain,
+  CryptoServiceX509GetCertFromCertChain,
+  CryptoServiceAsn1GetTag,
+  CryptoServiceX509GetExtendedBasicConstraints
 };
diff --git a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
index 52b44ca4f8..6338ac8f55 100644
--- a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
+++ b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
@@ -187,16 +187,30 @@ typedef struct {
   } Sha512;
   union {
     struct {
-      UINT8    GetSubjectName             : 1;
-      UINT8    GetCommonName              : 1;
-      UINT8    GetOrganizationName        : 1;
-      UINT8    VerifyCert                 : 1;
-      UINT8    ConstructCertificate       : 1;
-      UINT8    ConstructCertificateStack  : 1;
-      UINT8    ConstructCertificateStackV : 1;
-      UINT8    Free                       : 1;
-      UINT8    StackFree                  : 1;
-      UINT8    GetTBSCert                 : 1;
+      UINT8    GetSubjectName              : 1;
+      UINT8    GetCommonName               : 1;
+      UINT8    GetOrganizationName         : 1;
+      UINT8    VerifyCert                  : 1;
+      UINT8    ConstructCertificate        : 1;
+      UINT8    ConstructCertificateStack   : 1;
+      UINT8    ConstructCertificateStackV  : 1;
+      UINT8    Free                        : 1;
+      UINT8    StackFree                   : 1;
+      UINT8    GetTBSCert                  : 1;
+      UINT8    GetVersion                  : 1;
+      UINT8    GetSerialNumber             : 1;
+      UINT8    GetIssuerName               : 1;
+      UINT8    GetSignatureAlgorithm       : 1;
+      UINT8    GetExtensionData            : 1;
+      UINT8    GetExtendedKeyUsage         : 1;
+      UINT8    GetValidity                 : 1;
+      UINT8    SetDateTime                 : 1;
+      UINT8    CompareDateTime             : 1;
+      UINT8    GetKeyUsage                 : 1;
+      UINT8    VerifyCertChain             : 1;
+      UINT8    GetCertFromCertChain        : 1;
+      UINT8    Asn1GetTag                  : 1;
+      UINT8    GetExtendedBasicConstraints : 1;
     } Services;
     UINT32    Family;
   } X509;
diff --git a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
index ce6981f091..5c7b536c75 100644
--- a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
+++ b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
@@ -2322,6 +2322,421 @@ X509GetTBSCert (
   CALL_CRYPTO_SERVICE (X509GetTBSCert, (Cert, CertSize, TBSCert, TBSCertSize), FALSE);
 }
 
+/**
+  Retrieve the version from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     Version      Pointer to the retrieved version integer.
+
+  @retval TRUE           The certificate version retrieved successfully.
+  @retval FALSE          If  Cert is NULL or CertSize is Zero.
+  @retval FALSE          The operation is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetVersion (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINTN        *Version
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetVersion, (Cert, CertSize, Version), FALSE);
+}
+
+/**
+  Retrieve the serialNumber from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     SerialNumber  Pointer to the retrieved certificate SerialNumber bytes.
+  @param[in, out] SerialNumberSize  The size in bytes of the SerialNumber buffer on input,
+                               and the size of buffer returned SerialNumber on output.
+
+  @retval TRUE                     The certificate serialNumber retrieved successfully.
+  @retval FALSE                    If Cert is NULL or CertSize is Zero.
+                                   If SerialNumberSize is NULL.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SerialNumber exists.
+  @retval FALSE                    If the SerialNumber is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   SerialNumberSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSerialNumber (
+  IN      CONST UINT8 *Cert,
+  IN      UINTN CertSize,
+  OUT     UINT8 *SerialNumber, OPTIONAL
+  IN OUT  UINTN         *SerialNumberSize
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetSerialNumber, (Cert, CertSize, SerialNumber, SerialNumberSize), FALSE);
+}
+
+/**
+  Retrieve the issuer bytes from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     CertIssuer  Pointer to the retrieved certificate subject bytes.
+  @param[in, out] CertIssuerSize  The size in bytes of the CertIssuer buffer on input,
+                               and the size of buffer returned CertSubject on output.
+
+  @retval  TRUE   The certificate issuer retrieved successfully.
+  @retval  FALSE  Invalid certificate, or the CertIssuerSize is too small for the result.
+                  The CertIssuerSize will be updated with the required size.
+  @retval  FALSE  This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetIssuerName (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINT8        *CertIssuer,
+  IN OUT  UINTN        *CertIssuerSize
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetIssuerName, (Cert, CertSize, CertIssuer, CertIssuerSize), FALSE);
+}
+
+/**
+  Retrieve the Signature Algorithm from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Oid              Signature Algorithm Object identifier buffer.
+  @param[in,out]  OidSize          Signature Algorithm Object identifier buffer size
+
+  @retval TRUE           The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If OidSize is NULL.
+                                   If Oid is not NULL and *OidSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SignatureType.
+  @retval FALSE                    If the Oid is NULL. The required buffer size
+                                   is returned in the OidSize.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSignatureAlgorithm (
+  IN CONST UINT8 *Cert,
+  IN       UINTN CertSize,
+  OUT   UINT8 *Oid, OPTIONAL
+  IN OUT   UINTN       *OidSize
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetSignatureAlgorithm, (Cert, CertSize, Oid, OidSize), FALSE);
+}
+
+/**
+  Retrieve Extension data from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[in]      Oid              Object identifier buffer
+  @param[in]      OidSize          Object identifier buffer size
+  @param[out]     ExtensionData    Extension bytes.
+  @param[in, out] ExtensionDataSize Extension bytes size.
+
+  @retval TRUE                     The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If ExtensionDataSize is NULL.
+                                   If ExtensionData is not NULL and *ExtensionDataSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no Extension entry match Oid.
+  @retval FALSE                    If the ExtensionData is NULL. The required buffer size
+                                   is returned in the ExtensionDataSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtensionData (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     CONST UINT8  *Oid,
+  IN     UINTN        OidSize,
+  OUT UINT8           *ExtensionData,
+  IN OUT UINTN        *ExtensionDataSize
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetExtensionData, (Cert, CertSize, Oid, OidSize, ExtensionData, ExtensionDataSize), FALSE);
+}
+
+/**
+  Retrieve the Extended Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage bytes.
+  @param[in, out] UsageSize        Key Usage buffer sizs in bytes.
+
+  @retval TRUE                     The Usage bytes retrieve successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If CertSize is NULL.
+                                   If Usage is not NULL and *UsageSize is 0.
+                                   If Cert is invalid.
+  @retval FALSE                    If the Usage is NULL. The required buffer size
+                                   is returned in the UsageSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtendedKeyUsage (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  OUT UINT8           *Usage,
+  IN OUT UINTN        *UsageSize
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetExtendedKeyUsage, (Cert, CertSize, Usage, UsageSize), FALSE);
+}
+
+/**
+  Retrieve the Validity from one X.509 certificate
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[in]      From         notBefore Pointer to DateTime object.
+  @param[in,out]  FromSize     notBefore DateTime object size.
+  @param[in]      To           notAfter Pointer to DateTime object.
+  @param[in,out]  ToSize       notAfter DateTime object size.
+
+  Note: X509CompareDateTime to compare DateTime oject
+        x509SetDateTime to get a DateTime object from a DateTimeStr
+
+  @retval  TRUE   The certificate Validity retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Validity retrieve failed.
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetValidity  (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     UINT8        *From,
+  IN OUT UINTN        *FromSize,
+  IN     UINT8        *To,
+  IN OUT UINTN        *ToSize
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetValidity, (Cert, CertSize, From, FromSize, To, ToSize), FALSE);
+}
+
+/**
+  Format a DateTime object into DataTime Buffer
+
+  If DateTimeStr is NULL, then return FALSE.
+  If DateTimeSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      DateTimeStr      DateTime string like YYYYMMDDhhmmssZ
+                                   Ref: https://www.w3.org/TR/NOTE-datetime
+                                   Z stand for UTC time
+  @param[out]     DateTime         Pointer to a DateTime object.
+  @param[in,out]  DateTimeSize     DateTime object buffer size.
+
+  @retval TRUE                     The DateTime object create successfully.
+  @retval FALSE                    If DateTimeStr is NULL.
+                                   If DateTimeSize is NULL.
+                                   If DateTime is not NULL and *DateTimeSize is 0.
+                                   If Year Month Day Hour Minute Second combination is invalid datetime.
+  @retval FALSE                    If the DateTime is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   DateTimeSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509SetDateTime (
+  IN     CHAR8  *DateTimeStr,
+  OUT VOID      *DateTime,
+  IN OUT UINTN  *DateTimeSize
+  )
+{
+  CALL_CRYPTO_SERVICE (X509SetDateTime, (DateTimeStr, DateTime, DateTimeSize), FALSE);
+}
+
+/**
+  Compare DateTime1 object and DateTime2 object.
+
+  If DateTime1 is NULL, then return -2.
+  If DateTime2 is NULL, then return -2.
+  If DateTime1 == DateTime2, then return 0
+  If DateTime1 > DateTime2, then return 1
+  If DateTime1 < DateTime2, then return -1
+
+  @param[in]      DateTime1         Pointer to a DateTime Ojbect
+  @param[in]      DateTime2         Pointer to a DateTime Object
+
+  @retval  0      If DateTime1 == DateTime2
+  @retval  1      If DateTime1 > DateTime2
+  @retval  -1     If DateTime1 < DateTime2
+**/
+INT32
+EFIAPI
+X509CompareDateTime (
+  IN CONST  VOID  *DateTime1,
+  IN CONST  VOID  *DateTime2
+  )
+{
+  CALL_CRYPTO_SERVICE (X509CompareDateTime, (DateTime1, DateTime2), FALSE);
+}
+
+/**
+  Retrieve the Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage (CRYPTO_X509_KU_*)
+
+  @retval  TRUE   The certificate Key Usage retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Usage is NULL
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetKeyUsage (
+  IN    CONST UINT8  *Cert,
+  IN    UINTN        CertSize,
+  OUT   UINTN        *Usage
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetKeyUsage, (Cert, CertSize, Usage), FALSE);
+}
+
+/**
+  Verify one X509 certificate was issued by the trusted CA.
+  @param[in]      RootCert          Trusted Root Certificate buffer
+
+  @param[in]      RootCertLength    Trusted Root Certificate buffer length
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @retval  TRUE   All cerificates was issued by the first certificate in X509Certchain.
+  @retval  FALSE  Invalid certificate or the certificate was not issued by the given
+                  trusted CA.
+**/
+BOOLEAN
+EFIAPI
+X509VerifyCertChain (
+  IN CONST UINT8  *RootCert,
+  IN UINTN        RootCertLength,
+  IN CONST UINT8  *CertChain,
+  IN UINTN        CertChainLength
+  )
+{
+  CALL_CRYPTO_SERVICE (X509VerifyCertChain, (RootCert, RootCertLength, CertChain, CertChainLength), FALSE);
+}
+
+/**
+  Get one X509 certificate from CertChain.
+
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @param[in]      CertIndex         Index of certificate.
+
+  @param[out]     Cert              The certificate at the index of CertChain.
+  @param[out]     CertLength        The length certificate at the index of CertChain.
+
+  @retval  TRUE   Success.
+  @retval  FALSE  Failed to get certificate from certificate chain.
+**/
+BOOLEAN
+EFIAPI
+X509GetCertFromCertChain (
+  IN CONST UINT8   *CertChain,
+  IN UINTN         CertChainLength,
+  IN CONST INT32   CertIndex,
+  OUT CONST UINT8  **Cert,
+  OUT UINTN        *CertLength
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetCertFromCertChain, (CertChain, CertChainLength, CertIndex, Cert, CertLength), FALSE);
+}
+
+/**
+  Retrieve the tag and length of the tag.
+
+  @param Ptr      The position in the ASN.1 data
+  @param End      End of data
+  @param Length   The variable that will receive the length
+  @param Tag      The expected tag
+
+  @retval      TRUE   Get tag successful
+  @retval      FALSe  Failed to get tag or tag not match
+**/
+BOOLEAN
+EFIAPI
+Asn1GetTag (
+  IN OUT UINT8   **Ptr,
+  IN     UINT8   *End,
+  OUT UINTN      *Length,
+  IN     UINT32  Tag
+  )
+{
+  CALL_CRYPTO_SERVICE (Asn1GetTag, (Ptr, End, Length, Tag), FALSE);
+}
+
+/**
+  Retrieve the basic constraints from one X.509 certificate.
+
+  @param[in]      Cert                     Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize                 size of the X509 certificate in bytes.
+  @param[out]     BasicConstraints         basic constraints bytes.
+  @param[in, out] BasicConstraintsSize     basic constraints buffer sizs in bytes.
+
+  @retval TRUE                     The basic constraints retrieve successfully.
+  @retval FALSE                    If cert is NULL.
+                                   If cert_size is NULL.
+                                   If basic_constraints is not NULL and *basic_constraints_size is 0.
+                                   If cert is invalid.
+  @retval FALSE                    The required buffer size is small.
+                                   The return buffer size is basic_constraints_size parameter.
+  @retval FALSE                    If no Extension entry match oid.
+  @retval FALSE                    The operation is not supported.
+ **/
+BOOLEAN
+EFIAPI
+X509GetExtendedBasicConstraints             (
+  CONST UINT8  *Cert,
+  UINTN        CertSize,
+  UINT8        *BasicConstraints,
+  UINTN        *BasicConstraintsSize
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetExtendedBasicConstraints, (Cert, CertSize, BasicConstraints, BasicConstraintsSize), FALSE);
+}
+
 /**
   Derives a key from a password using a salt and iteration count, based on PKCS#5 v2.0
   password based encryption key derivation function PBKDF2, as specified in RFC 2898.
diff --git a/CryptoPkg/Private/Protocol/Crypto.h b/CryptoPkg/Private/Protocol/Crypto.h
index 3bf37575e9..ec9c074c7b 100644
--- a/CryptoPkg/Private/Protocol/Crypto.h
+++ b/CryptoPkg/Private/Protocol/Crypto.h
@@ -21,7 +21,7 @@
 /// the EDK II Crypto Protocol is extended, this version define must be
 /// increased.
 ///
-#define EDKII_CRYPTO_VERSION  12
+#define EDKII_CRYPTO_VERSION  13
 
 ///
 /// EDK II Crypto Protocol forward declaration
@@ -2351,6 +2351,381 @@ BOOLEAN
   OUT UINTN        *TBSCertSize
   );
 
+/**
+  Retrieve the version from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     Version      Pointer to the retrieved version integer.
+
+  @retval TRUE           The certificate version retrieved successfully.
+  @retval FALSE          If  Cert is NULL or CertSize is Zero.
+  @retval FALSE          The operation is not supported.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_VERSION)(
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINTN        *Version
+  );
+
+/**
+  Retrieve the serialNumber from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     SerialNumber  Pointer to the retrieved certificate SerialNumber bytes.
+  @param[in, out] SerialNumberSize  The size in bytes of the SerialNumber buffer on input,
+                               and the size of buffer returned SerialNumber on output.
+
+  @retval TRUE                     The certificate serialNumber retrieved successfully.
+  @retval FALSE                    If Cert is NULL or CertSize is Zero.
+                                   If SerialNumberSize is NULL.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SerialNumber exists.
+  @retval FALSE                    If the SerialNumber is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   SerialNumberSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_SERIAL_NUMBER)(
+  IN      CONST UINT8 *Cert,
+  IN      UINTN CertSize,
+  OUT     UINT8 *SerialNumber, OPTIONAL
+  IN OUT  UINTN         *SerialNumberSize
+  );
+
+/**
+  Retrieve the issuer bytes from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     CertIssuer  Pointer to the retrieved certificate subject bytes.
+  @param[in, out] CertIssuerSize  The size in bytes of the CertIssuer buffer on input,
+                               and the size of buffer returned CertSubject on output.
+
+  @retval  TRUE   The certificate issuer retrieved successfully.
+  @retval  FALSE  Invalid certificate, or the CertIssuerSize is too small for the result.
+                  The CertIssuerSize will be updated with the required size.
+  @retval  FALSE  This interface is not supported.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_ISSUER_NAME)(
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINT8        *CertIssuer,
+  IN OUT  UINTN        *CertIssuerSize
+  );
+
+/**
+  Retrieve the Signature Algorithm from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Oid              Signature Algorithm Object identifier buffer.
+  @param[in,out]  OidSize          Signature Algorithm Object identifier buffer size
+
+  @retval TRUE           The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If OidSize is NULL.
+                                   If Oid is not NULL and *OidSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SignatureType.
+  @retval FALSE                    If the Oid is NULL. The required buffer size
+                                   is returned in the OidSize.
+  @retval FALSE                    The operation is not supported.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_SIGNATURE_ALGORITHM)(
+  IN CONST UINT8 *Cert,
+  IN       UINTN CertSize,
+  OUT   UINT8 *Oid, OPTIONAL
+  IN OUT   UINTN       *OidSize
+  );
+
+/**
+  Retrieve Extension data from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[in]      Oid              Object identifier buffer
+  @param[in]      OidSize          Object identifier buffer size
+  @param[out]     ExtensionData    Extension bytes.
+  @param[in, out] ExtensionDataSize Extension bytes size.
+
+  @retval TRUE                     The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If ExtensionDataSize is NULL.
+                                   If ExtensionData is not NULL and *ExtensionDataSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no Extension entry match Oid.
+  @retval FALSE                    If the ExtensionData is NULL. The required buffer size
+                                   is returned in the ExtensionDataSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_EXTENSION_DATA)(
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     CONST UINT8  *Oid,
+  IN     UINTN        OidSize,
+  OUT UINT8           *ExtensionData,
+  IN OUT UINTN        *ExtensionDataSize
+  );
+
+/**
+  Retrieve the Extended Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage bytes.
+  @param[in, out] UsageSize        Key Usage buffer sizs in bytes.
+
+  @retval TRUE                     The Usage bytes retrieve successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If CertSize is NULL.
+                                   If Usage is not NULL and *UsageSize is 0.
+                                   If Cert is invalid.
+  @retval FALSE                    If the Usage is NULL. The required buffer size
+                                   is returned in the UsageSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_EXTENDED_KEY_USAGE)(
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  OUT UINT8           *Usage,
+  IN OUT UINTN        *UsageSize
+  );
+
+/**
+  Retrieve the Validity from one X.509 certificate
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     From         notBefore Pointer to DateTime object.
+  @param[in,out]  FromSize     notBefore DateTime object size.
+  @param[out]     To           notAfter Pointer to DateTime object.
+  @param[in,out]  ToSize       notAfter DateTime object size.
+
+  Note: X509CompareDateTime to compare DateTime oject
+        x509SetDateTime to get a DateTime object from a DateTimeStr
+
+  @retval  TRUE   The certificate Validity retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Validity retrieve failed.
+  @retval  FALSE  This interface is not supported.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_VALIDITY)(
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     UINT8        *From,
+  IN OUT UINTN        *FromSize,
+  IN     UINT8        *To,
+  IN OUT UINTN        *ToSize
+  );
+
+/**
+  Format a DateTime object into DataTime Buffer
+
+  If DateTimeStr is NULL, then return FALSE.
+  If DateTimeSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      DateTimeStr      DateTime string like YYYYMMDDhhmmssZ
+                                   Ref: https://www.w3.org/TR/NOTE-datetime
+                                   Z stand for UTC time
+  @param[in,out]  DateTime         Pointer to a DateTime object.
+  @param[in,out]  DateTimeSize     DateTime object buffer size.
+
+  @retval TRUE                     The DateTime object create successfully.
+  @retval FALSE                    If DateTimeStr is NULL.
+                                   If DateTimeSize is NULL.
+                                   If DateTime is not NULL and *DateTimeSize is 0.
+                                   If Year Month Day Hour Minute Second combination is invalid datetime.
+  @retval FALSE                    If the DateTime is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   DateTimeSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_SET_DATE_TIME)(
+  IN     CHAR8  *DateTimeStr,
+  OUT VOID      *DateTime,
+  IN OUT UINTN  *DateTimeSize
+  );
+
+/**
+  Compare DateTime1 object and DateTime2 object.
+
+  If DateTime1 is NULL, then return -2.
+  If DateTime2 is NULL, then return -2.
+  If DateTime1 == DateTime2, then return 0
+  If DateTime1 > DateTime2, then return 1
+  If DateTime1 < DateTime2, then return -1
+
+  @param[in]      DateTime1         Pointer to a DateTime Ojbect
+  @param[in]      DateTime2         Pointer to a DateTime Object
+
+  @retval  0      If DateTime1 == DateTime2
+  @retval  1      If DateTime1 > DateTime2
+  @retval  -1     If DateTime1 < DateTime2
+**/
+typedef
+INT32
+(EFIAPI *EDKII_CRYPTO_X509_COMPARE_DATE_TIME)(
+  IN CONST  VOID  *DateTime1,
+  IN CONST  VOID  *DateTime2
+  );
+
+/**
+  Retrieve the Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage (CRYPTO_X509_KU_*)
+
+  @retval  TRUE   The certificate Key Usage retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Usage is NULL
+  @retval  FALSE  This interface is not supported.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_KEY_USAGE)(
+  IN    CONST UINT8  *Cert,
+  IN    UINTN        CertSize,
+  OUT   UINTN        *Usage
+  );
+
+/**
+  Verify one X509 certificate was issued by the trusted CA.
+
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @param[in]      RootCert          Trusted Root Certificate buffer
+
+  @param[in]      RootCertLength    Trusted Root Certificate buffer length
+
+  @retval  TRUE   All cerificates was issued by the first certificate in X509Certchain.
+  @retval  FALSE  Invalid certificate or the certificate was not issued by the given
+                  trusted CA.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_VERIFY_CERT_CHAIN)(
+  IN CONST UINT8  *RootCert,
+  IN UINTN        RootCertLength,
+  IN CONST UINT8  *CertChain,
+  IN UINTN        CertChainLength
+  );
+
+/**
+  Get one X509 certificate from CertChain.
+
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @param[in]      CertIndex         Index of certificate.
+
+  @param[out]     Cert              The certificate at the index of CertChain.
+  @param[out]     CertLength        The length certificate at the index of CertChain.
+
+  @retval  TRUE   Success.
+  @retval  FALSE  Failed to get certificate from certificate chain.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_CERT_FROM_CERT_CHAIN)(
+  IN CONST UINT8   *CertChain,
+  IN UINTN         CertChainLength,
+  IN CONST INT32   CertIndex,
+  OUT CONST UINT8  **Cert,
+  OUT UINTN        *CertLength
+  );
+
+/**
+  Retrieve the tag and length of the tag.
+
+  @param Ptr      The position in the ASN.1 data
+  @param End      End of data
+  @param Length   The variable that will receive the length
+  @param Tag      The expected tag
+
+  @retval      TRUE   Get tag successful
+  @retval      FALSe  Failed to get tag or tag not match
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_ASN1_GET_TAG)(
+  IN OUT UINT8   **Ptr,
+  IN     UINT8   *End,
+  OUT UINTN      *Length,
+  IN     UINT32  Tag
+  );
+
+/**
+  Retrieve the basic constraints from one X.509 certificate.
+
+  @param[in]      Cert                     Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize                 size of the X509 certificate in bytes.
+  @param[out]     BasicConstraints         basic constraints bytes.
+  @param[in, out] BasicConstraintsSize     basic constraints buffer sizs in bytes.
+
+  @retval TRUE                     The basic constraints retrieve successfully.
+  @retval FALSE                    If cert is NULL.
+                                   If cert_size is NULL.
+                                   If basic_constraints is not NULL and *basic_constraints_size is 0.
+                                   If cert is invalid.
+  @retval FALSE                    The required buffer size is small.
+                                   The return buffer size is basic_constraints_size parameter.
+  @retval FALSE                    If no Extension entry match oid.
+  @retval FALSE                    The operation is not supported.
+ **/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_EXTENDED_BASIC_CONSTRAINTS)(
+  CONST UINT8  *Cert,
+  UINTN        CertSize,
+  UINT8        *BasicConstraints,
+  UINTN        *BasicConstraintsSize
+  );
+
 // =====================================================================================
 //    Symmetric Cryptography Primitive
 // =====================================================================================
@@ -4294,235 +4669,250 @@ BOOLEAN
 ///
 struct _EDKII_CRYPTO_PROTOCOL {
   /// Version
-  EDKII_CRYPTO_GET_VERSION                           GetVersion;
+  EDKII_CRYPTO_GET_VERSION                            GetVersion;
   /// HMAC MD5 - deprecated and unsupported
-  DEPRECATED_EDKII_CRYPTO_HMAC_MD5_NEW               DeprecatedHmacMd5New;
-  DEPRECATED_EDKII_CRYPTO_HMAC_MD5_FREE              DeprecatedHmacMd5Free;
-  DEPRECATED_EDKII_CRYPTO_HMAC_MD5_SET_KEY           DeprecatedHmacMd5SetKey;
-  DEPRECATED_EDKII_CRYPTO_HMAC_MD5_DUPLICATE         DeprecatedHmacMd5Duplicate;
-  DEPRECATED_EDKII_CRYPTO_HMAC_MD5_UPDATE            DeprecatedHmacMd5Update;
-  DEPRECATED_EDKII_CRYPTO_HMAC_MD5_FINAL             DeprecatedHmacMd5Final;
+  DEPRECATED_EDKII_CRYPTO_HMAC_MD5_NEW                DeprecatedHmacMd5New;
+  DEPRECATED_EDKII_CRYPTO_HMAC_MD5_FREE               DeprecatedHmacMd5Free;
+  DEPRECATED_EDKII_CRYPTO_HMAC_MD5_SET_KEY            DeprecatedHmacMd5SetKey;
+  DEPRECATED_EDKII_CRYPTO_HMAC_MD5_DUPLICATE          DeprecatedHmacMd5Duplicate;
+  DEPRECATED_EDKII_CRYPTO_HMAC_MD5_UPDATE             DeprecatedHmacMd5Update;
+  DEPRECATED_EDKII_CRYPTO_HMAC_MD5_FINAL              DeprecatedHmacMd5Final;
   /// HMAC SHA1 - deprecated and unsupported
-  DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_NEW              DeprecatedHmacSha1New;
-  DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_FREE             DeprecatedHmacSha1Free;
-  DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_SET_KEY          DeprecatedHmacSha1SetKey;
-  DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_DUPLICATE        DeprecatedHmacSha1Duplicate;
-  DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_UPDATE           DeprecatedHmacSha1Update;
-  DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_FINAL            DeprecatedHmacSha1Final;
+  DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_NEW               DeprecatedHmacSha1New;
+  DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_FREE              DeprecatedHmacSha1Free;
+  DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_SET_KEY           DeprecatedHmacSha1SetKey;
+  DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_DUPLICATE         DeprecatedHmacSha1Duplicate;
+  DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_UPDATE            DeprecatedHmacSha1Update;
+  DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_FINAL             DeprecatedHmacSha1Final;
   /// HMAC SHA256
-  EDKII_CRYPTO_HMAC_SHA256_NEW                       HmacSha256New;
-  EDKII_CRYPTO_HMAC_SHA256_FREE                      HmacSha256Free;
-  EDKII_CRYPTO_HMAC_SHA256_SET_KEY                   HmacSha256SetKey;
-  EDKII_CRYPTO_HMAC_SHA256_DUPLICATE                 HmacSha256Duplicate;
-  EDKII_CRYPTO_HMAC_SHA256_UPDATE                    HmacSha256Update;
-  EDKII_CRYPTO_HMAC_SHA256_FINAL                     HmacSha256Final;
+  EDKII_CRYPTO_HMAC_SHA256_NEW                        HmacSha256New;
+  EDKII_CRYPTO_HMAC_SHA256_FREE                       HmacSha256Free;
+  EDKII_CRYPTO_HMAC_SHA256_SET_KEY                    HmacSha256SetKey;
+  EDKII_CRYPTO_HMAC_SHA256_DUPLICATE                  HmacSha256Duplicate;
+  EDKII_CRYPTO_HMAC_SHA256_UPDATE                     HmacSha256Update;
+  EDKII_CRYPTO_HMAC_SHA256_FINAL                      HmacSha256Final;
   /// Md4 - deprecated and unsupported
-  DEPRECATED_EDKII_CRYPTO_MD4_GET_CONTEXT_SIZE       DeprecatedMd4GetContextSize;
-  DEPRECATED_EDKII_CRYPTO_MD4_INIT                   DeprecatedMd4Init;
-  DEPRECATED_EDKII_CRYPTO_MD4_DUPLICATE              DeprecatedMd4Duplicate;
-  DEPRECATED_EDKII_CRYPTO_MD4_UPDATE                 DeprecatedMd4Update;
-  DEPRECATED_EDKII_CRYPTO_MD4_FINAL                  DeprecatedMd4Final;
-  DEPRECATED_EDKII_CRYPTO_MD4_HASH_ALL               DeprecatedMd4HashAll;
+  DEPRECATED_EDKII_CRYPTO_MD4_GET_CONTEXT_SIZE        DeprecatedMd4GetContextSize;
+  DEPRECATED_EDKII_CRYPTO_MD4_INIT                    DeprecatedMd4Init;
+  DEPRECATED_EDKII_CRYPTO_MD4_DUPLICATE               DeprecatedMd4Duplicate;
+  DEPRECATED_EDKII_CRYPTO_MD4_UPDATE                  DeprecatedMd4Update;
+  DEPRECATED_EDKII_CRYPTO_MD4_FINAL                   DeprecatedMd4Final;
+  DEPRECATED_EDKII_CRYPTO_MD4_HASH_ALL                DeprecatedMd4HashAll;
   /// Md5
-  EDKII_CRYPTO_MD5_GET_CONTEXT_SIZE                  Md5GetContextSize;
-  EDKII_CRYPTO_MD5_INIT                              Md5Init;
-  EDKII_CRYPTO_MD5_DUPLICATE                         Md5Duplicate;
-  EDKII_CRYPTO_MD5_UPDATE                            Md5Update;
-  EDKII_CRYPTO_MD5_FINAL                             Md5Final;
-  EDKII_CRYPTO_MD5_HASH_ALL                          Md5HashAll;
+  EDKII_CRYPTO_MD5_GET_CONTEXT_SIZE                   Md5GetContextSize;
+  EDKII_CRYPTO_MD5_INIT                               Md5Init;
+  EDKII_CRYPTO_MD5_DUPLICATE                          Md5Duplicate;
+  EDKII_CRYPTO_MD5_UPDATE                             Md5Update;
+  EDKII_CRYPTO_MD5_FINAL                              Md5Final;
+  EDKII_CRYPTO_MD5_HASH_ALL                           Md5HashAll;
   /// Pkcs
-  EDKII_CRYPTO_PKCS1_ENCRYPT_V2                      Pkcs1v2Encrypt;
-  EDKII_CRYPTO_PKCS5_PW_HASH                         Pkcs5HashPassword;
-  EDKII_CRYPTO_PKCS7_VERIFY                          Pkcs7Verify;
-  EDKII_CRYPTO_PKCS7_VERIFY_EKU                      VerifyEKUsInPkcs7Signature;
-  EDKII_CRYPTO_PKCS7_GET_SIGNERS                     Pkcs7GetSigners;
-  EDKII_CRYPTO_PKCS7_FREE_SIGNERS                    Pkcs7FreeSigners;
-  EDKII_CRYPTO_PKCS7_SIGN                            Pkcs7Sign;
-  EDKII_CRYPTO_PKCS7_GET_ATTACHED_CONTENT            Pkcs7GetAttachedContent;
-  EDKII_CRYPTO_PKCS7_GET_CERTIFICATES_LIST           Pkcs7GetCertificatesList;
-  EDKII_CRYPTO_AUTHENTICODE_VERIFY                   AuthenticodeVerify;
-  EDKII_CRYPTO_IMAGE_TIMESTAMP_VERIFY                ImageTimestampVerify;
+  EDKII_CRYPTO_PKCS1_ENCRYPT_V2                       Pkcs1v2Encrypt;
+  EDKII_CRYPTO_PKCS5_PW_HASH                          Pkcs5HashPassword;
+  EDKII_CRYPTO_PKCS7_VERIFY                           Pkcs7Verify;
+  EDKII_CRYPTO_PKCS7_VERIFY_EKU                       VerifyEKUsInPkcs7Signature;
+  EDKII_CRYPTO_PKCS7_GET_SIGNERS                      Pkcs7GetSigners;
+  EDKII_CRYPTO_PKCS7_FREE_SIGNERS                     Pkcs7FreeSigners;
+  EDKII_CRYPTO_PKCS7_SIGN                             Pkcs7Sign;
+  EDKII_CRYPTO_PKCS7_GET_ATTACHED_CONTENT             Pkcs7GetAttachedContent;
+  EDKII_CRYPTO_PKCS7_GET_CERTIFICATES_LIST            Pkcs7GetCertificatesList;
+  EDKII_CRYPTO_AUTHENTICODE_VERIFY                    AuthenticodeVerify;
+  EDKII_CRYPTO_IMAGE_TIMESTAMP_VERIFY                 ImageTimestampVerify;
   /// DH
-  EDKII_CRYPTO_DH_NEW                                DhNew;
-  EDKII_CRYPTO_DH_FREE                               DhFree;
-  EDKII_CRYPTO_DH_GENERATE_PARAMETER                 DhGenerateParameter;
-  EDKII_CRYPTO_DH_SET_PARAMETER                      DhSetParameter;
-  EDKII_CRYPTO_DH_GENERATE_KEY                       DhGenerateKey;
-  EDKII_CRYPTO_DH_COMPUTE_KEY                        DhComputeKey;
+  EDKII_CRYPTO_DH_NEW                                 DhNew;
+  EDKII_CRYPTO_DH_FREE                                DhFree;
+  EDKII_CRYPTO_DH_GENERATE_PARAMETER                  DhGenerateParameter;
+  EDKII_CRYPTO_DH_SET_PARAMETER                       DhSetParameter;
+  EDKII_CRYPTO_DH_GENERATE_KEY                        DhGenerateKey;
+  EDKII_CRYPTO_DH_COMPUTE_KEY                         DhComputeKey;
   /// Random
-  EDKII_CRYPTO_RANDOM_SEED                           RandomSeed;
-  EDKII_CRYPTO_RANDOM_BYTES                          RandomBytes;
+  EDKII_CRYPTO_RANDOM_SEED                            RandomSeed;
+  EDKII_CRYPTO_RANDOM_BYTES                           RandomBytes;
   /// RSA
-  EDKII_CRYPTO_RSA_VERIFY_PKCS1                      RsaVerifyPkcs1;
-  EDKII_CRYPTO_RSA_NEW                               RsaNew;
-  EDKII_CRYPTO_RSA_FREE                              RsaFree;
-  EDKII_CRYPTO_RSA_SET_KEY                           RsaSetKey;
-  EDKII_CRYPTO_RSA_GET_KEY                           RsaGetKey;
-  EDKII_CRYPTO_RSA_GENERATE_KEY                      RsaGenerateKey;
-  EDKII_CRYPTO_RSA_CHECK_KEY                         RsaCheckKey;
-  EDKII_CRYPTO_RSA_PKCS1_SIGN                        RsaPkcs1Sign;
-  EDKII_CRYPTO_RSA_PKCS1_VERIFY                      RsaPkcs1Verify;
-  EDKII_CRYPTO_RSA_GET_PRIVATE_KEY_FROM_PEM          RsaGetPrivateKeyFromPem;
-  EDKII_CRYPTO_RSA_GET_PUBLIC_KEY_FROM_X509          RsaGetPublicKeyFromX509;
+  EDKII_CRYPTO_RSA_VERIFY_PKCS1                       RsaVerifyPkcs1;
+  EDKII_CRYPTO_RSA_NEW                                RsaNew;
+  EDKII_CRYPTO_RSA_FREE                               RsaFree;
+  EDKII_CRYPTO_RSA_SET_KEY                            RsaSetKey;
+  EDKII_CRYPTO_RSA_GET_KEY                            RsaGetKey;
+  EDKII_CRYPTO_RSA_GENERATE_KEY                       RsaGenerateKey;
+  EDKII_CRYPTO_RSA_CHECK_KEY                          RsaCheckKey;
+  EDKII_CRYPTO_RSA_PKCS1_SIGN                         RsaPkcs1Sign;
+  EDKII_CRYPTO_RSA_PKCS1_VERIFY                       RsaPkcs1Verify;
+  EDKII_CRYPTO_RSA_GET_PRIVATE_KEY_FROM_PEM           RsaGetPrivateKeyFromPem;
+  EDKII_CRYPTO_RSA_GET_PUBLIC_KEY_FROM_X509           RsaGetPublicKeyFromX509;
   /// Sha1
-  EDKII_CRYPTO_SHA1_GET_CONTEXT_SIZE                 Sha1GetContextSize;
-  EDKII_CRYPTO_SHA1_INIT                             Sha1Init;
-  EDKII_CRYPTO_SHA1_DUPLICATE                        Sha1Duplicate;
-  EDKII_CRYPTO_SHA1_UPDATE                           Sha1Update;
-  EDKII_CRYPTO_SHA1_FINAL                            Sha1Final;
-  EDKII_CRYPTO_SHA1_HASH_ALL                         Sha1HashAll;
+  EDKII_CRYPTO_SHA1_GET_CONTEXT_SIZE                  Sha1GetContextSize;
+  EDKII_CRYPTO_SHA1_INIT                              Sha1Init;
+  EDKII_CRYPTO_SHA1_DUPLICATE                         Sha1Duplicate;
+  EDKII_CRYPTO_SHA1_UPDATE                            Sha1Update;
+  EDKII_CRYPTO_SHA1_FINAL                             Sha1Final;
+  EDKII_CRYPTO_SHA1_HASH_ALL                          Sha1HashAll;
   /// Sha256
-  EDKII_CRYPTO_SHA256_GET_CONTEXT_SIZE               Sha256GetContextSize;
-  EDKII_CRYPTO_SHA256_INIT                           Sha256Init;
-  EDKII_CRYPTO_SHA256_DUPLICATE                      Sha256Duplicate;
-  EDKII_CRYPTO_SHA256_UPDATE                         Sha256Update;
-  EDKII_CRYPTO_SHA256_FINAL                          Sha256Final;
-  EDKII_CRYPTO_SHA256_HASH_ALL                       Sha256HashAll;
+  EDKII_CRYPTO_SHA256_GET_CONTEXT_SIZE                Sha256GetContextSize;
+  EDKII_CRYPTO_SHA256_INIT                            Sha256Init;
+  EDKII_CRYPTO_SHA256_DUPLICATE                       Sha256Duplicate;
+  EDKII_CRYPTO_SHA256_UPDATE                          Sha256Update;
+  EDKII_CRYPTO_SHA256_FINAL                           Sha256Final;
+  EDKII_CRYPTO_SHA256_HASH_ALL                        Sha256HashAll;
   /// Sha384
-  EDKII_CRYPTO_SHA384_GET_CONTEXT_SIZE               Sha384GetContextSize;
-  EDKII_CRYPTO_SHA384_INIT                           Sha384Init;
-  EDKII_CRYPTO_SHA384_DUPLICATE                      Sha384Duplicate;
-  EDKII_CRYPTO_SHA384_UPDATE                         Sha384Update;
-  EDKII_CRYPTO_SHA384_FINAL                          Sha384Final;
-  EDKII_CRYPTO_SHA384_HASH_ALL                       Sha384HashAll;
+  EDKII_CRYPTO_SHA384_GET_CONTEXT_SIZE                Sha384GetContextSize;
+  EDKII_CRYPTO_SHA384_INIT                            Sha384Init;
+  EDKII_CRYPTO_SHA384_DUPLICATE                       Sha384Duplicate;
+  EDKII_CRYPTO_SHA384_UPDATE                          Sha384Update;
+  EDKII_CRYPTO_SHA384_FINAL                           Sha384Final;
+  EDKII_CRYPTO_SHA384_HASH_ALL                        Sha384HashAll;
   /// Sha512
-  EDKII_CRYPTO_SHA512_GET_CONTEXT_SIZE               Sha512GetContextSize;
-  EDKII_CRYPTO_SHA512_INIT                           Sha512Init;
-  EDKII_CRYPTO_SHA512_DUPLICATE                      Sha512Duplicate;
-  EDKII_CRYPTO_SHA512_UPDATE                         Sha512Update;
-  EDKII_CRYPTO_SHA512_FINAL                          Sha512Final;
-  EDKII_CRYPTO_SHA512_HASH_ALL                       Sha512HashAll;
+  EDKII_CRYPTO_SHA512_GET_CONTEXT_SIZE                Sha512GetContextSize;
+  EDKII_CRYPTO_SHA512_INIT                            Sha512Init;
+  EDKII_CRYPTO_SHA512_DUPLICATE                       Sha512Duplicate;
+  EDKII_CRYPTO_SHA512_UPDATE                          Sha512Update;
+  EDKII_CRYPTO_SHA512_FINAL                           Sha512Final;
+  EDKII_CRYPTO_SHA512_HASH_ALL                        Sha512HashAll;
   /// X509
-  EDKII_CRYPTO_X509_GET_SUBJECT_NAME                 X509GetSubjectName;
-  EDKII_CRYPTO_X509_GET_COMMON_NAME                  X509GetCommonName;
-  EDKII_CRYPTO_X509_GET_ORGANIZATION_NAME            X509GetOrganizationName;
-  EDKII_CRYPTO_X509_VERIFY_CERT                      X509VerifyCert;
-  EDKII_CRYPTO_X509_CONSTRUCT_CERTIFICATE            X509ConstructCertificate;
-  EDKII_CRYPTO_X509_CONSTRUCT_CERTIFICATE_STACK      X509ConstructCertificateStack;
-  EDKII_CRYPTO_X509_FREE                             X509Free;
-  EDKII_CRYPTO_X509_STACK_FREE                       X509StackFree;
-  EDKII_CRYPTO_X509_GET_TBS_CERT                     X509GetTBSCert;
+  EDKII_CRYPTO_X509_GET_SUBJECT_NAME                  X509GetSubjectName;
+  EDKII_CRYPTO_X509_GET_COMMON_NAME                   X509GetCommonName;
+  EDKII_CRYPTO_X509_GET_ORGANIZATION_NAME             X509GetOrganizationName;
+  EDKII_CRYPTO_X509_VERIFY_CERT                       X509VerifyCert;
+  EDKII_CRYPTO_X509_CONSTRUCT_CERTIFICATE             X509ConstructCertificate;
+  EDKII_CRYPTO_X509_CONSTRUCT_CERTIFICATE_STACK       X509ConstructCertificateStack;
+  EDKII_CRYPTO_X509_FREE                              X509Free;
+  EDKII_CRYPTO_X509_STACK_FREE                        X509StackFree;
+  EDKII_CRYPTO_X509_GET_TBS_CERT                      X509GetTBSCert;
   /// TDES - deprecated and unsupported
-  DEPRECATED_EDKII_CRYPTO_TDES_GET_CONTEXT_SIZE      DeprecatedTdesGetContextSize;
-  DEPRECATED_EDKII_CRYPTO_TDES_INIT                  DeprecatedTdesInit;
-  DEPRECATED_EDKII_CRYPTO_TDES_ECB_ENCRYPT           DeprecatedTdesEcbEncrypt;
-  DEPRECATED_EDKII_CRYPTO_TDES_ECB_DECRYPT           DeprecatedTdesEcbDecrypt;
-  DEPRECATED_EDKII_CRYPTO_TDES_CBC_ENCRYPT           DeprecatedTdesCbcEncrypt;
-  DEPRECATED_EDKII_CRYPTO_TDES_CBC_DECRYPT           DeprecatedTdesCbcDecrypt;
+  DEPRECATED_EDKII_CRYPTO_TDES_GET_CONTEXT_SIZE       DeprecatedTdesGetContextSize;
+  DEPRECATED_EDKII_CRYPTO_TDES_INIT                   DeprecatedTdesInit;
+  DEPRECATED_EDKII_CRYPTO_TDES_ECB_ENCRYPT            DeprecatedTdesEcbEncrypt;
+  DEPRECATED_EDKII_CRYPTO_TDES_ECB_DECRYPT            DeprecatedTdesEcbDecrypt;
+  DEPRECATED_EDKII_CRYPTO_TDES_CBC_ENCRYPT            DeprecatedTdesCbcEncrypt;
+  DEPRECATED_EDKII_CRYPTO_TDES_CBC_DECRYPT            DeprecatedTdesCbcDecrypt;
   /// AES - ECB Mode is deprecated and unsupported
-  EDKII_CRYPTO_AES_GET_CONTEXT_SIZE                  AesGetContextSize;
-  EDKII_CRYPTO_AES_INIT                              AesInit;
-  DEPRECATED_EDKII_CRYPTO_AES_ECB_ENCRYPT            DeprecatedAesEcbEncrypt;
-  DEPRECATED_EDKII_CRYPTO_AES_ECB_DECRYPT            DeprecatedAesEcbDecrypt;
-  EDKII_CRYPTO_AES_CBC_ENCRYPT                       AesCbcEncrypt;
-  EDKII_CRYPTO_AES_CBC_DECRYPT                       AesCbcDecrypt;
+  EDKII_CRYPTO_AES_GET_CONTEXT_SIZE                   AesGetContextSize;
+  EDKII_CRYPTO_AES_INIT                               AesInit;
+  DEPRECATED_EDKII_CRYPTO_AES_ECB_ENCRYPT             DeprecatedAesEcbEncrypt;
+  DEPRECATED_EDKII_CRYPTO_AES_ECB_DECRYPT             DeprecatedAesEcbDecrypt;
+  EDKII_CRYPTO_AES_CBC_ENCRYPT                        AesCbcEncrypt;
+  EDKII_CRYPTO_AES_CBC_DECRYPT                        AesCbcDecrypt;
   /// Arc4 - deprecated and unsupported
-  DEPRECATED_EDKII_CRYPTO_ARC4_GET_CONTEXT_SIZE      DeprecatedArc4GetContextSize;
-  DEPRECATED_EDKII_CRYPTO_ARC4_INIT                  DeprecatedArc4Init;
-  DEPRECATED_EDKII_CRYPTO_ARC4_ENCRYPT               DeprecatedArc4Encrypt;
-  DEPRECATED_EDKII_CRYPTO_ARC4_DECRYPT               DeprecatedArc4Decrypt;
-  DEPRECATED_EDKII_CRYPTO_ARC4_RESET                 DeprecatedArc4Reset;
+  DEPRECATED_EDKII_CRYPTO_ARC4_GET_CONTEXT_SIZE       DeprecatedArc4GetContextSize;
+  DEPRECATED_EDKII_CRYPTO_ARC4_INIT                   DeprecatedArc4Init;
+  DEPRECATED_EDKII_CRYPTO_ARC4_ENCRYPT                DeprecatedArc4Encrypt;
+  DEPRECATED_EDKII_CRYPTO_ARC4_DECRYPT                DeprecatedArc4Decrypt;
+  DEPRECATED_EDKII_CRYPTO_ARC4_RESET                  DeprecatedArc4Reset;
   /// SM3
-  EDKII_CRYPTO_SM3_GET_CONTEXT_SIZE                  Sm3GetContextSize;
-  EDKII_CRYPTO_SM3_INIT                              Sm3Init;
-  EDKII_CRYPTO_SM3_DUPLICATE                         Sm3Duplicate;
-  EDKII_CRYPTO_SM3_UPDATE                            Sm3Update;
-  EDKII_CRYPTO_SM3_FINAL                             Sm3Final;
-  EDKII_CRYPTO_SM3_HASH_ALL                          Sm3HashAll;
+  EDKII_CRYPTO_SM3_GET_CONTEXT_SIZE                   Sm3GetContextSize;
+  EDKII_CRYPTO_SM3_INIT                               Sm3Init;
+  EDKII_CRYPTO_SM3_DUPLICATE                          Sm3Duplicate;
+  EDKII_CRYPTO_SM3_UPDATE                             Sm3Update;
+  EDKII_CRYPTO_SM3_FINAL                              Sm3Final;
+  EDKII_CRYPTO_SM3_HASH_ALL                           Sm3HashAll;
   /// HKDF
-  EDKII_CRYPTO_HKDF_SHA_256_EXTRACT_AND_EXPAND       HkdfSha256ExtractAndExpand;
+  EDKII_CRYPTO_HKDF_SHA_256_EXTRACT_AND_EXPAND        HkdfSha256ExtractAndExpand;
   /// X509 (Continued)
-  EDKII_CRYPTO_X509_CONSTRUCT_CERTIFICATE_STACK_V    X509ConstructCertificateStackV;
+  EDKII_CRYPTO_X509_CONSTRUCT_CERTIFICATE_STACK_V     X509ConstructCertificateStackV;
   /// TLS
-  EDKII_CRYPTO_TLS_INITIALIZE                        TlsInitialize;
-  EDKII_CRYPTO_TLS_CTX_FREE                          TlsCtxFree;
-  EDKII_CRYPTO_TLS_CTX_NEW                           TlsCtxNew;
-  EDKII_CRYPTO_TLS_FREE                              TlsFree;
-  EDKII_CRYPTO_TLS_NEW                               TlsNew;
-  EDKII_CRYPTO_TLS_IN_HANDSHAKE                      TlsInHandshake;
-  EDKII_CRYPTO_TLS_DO_HANDSHAKE                      TlsDoHandshake;
-  EDKII_CRYPTO_TLS_HANDLE_ALERT                      TlsHandleAlert;
-  EDKII_CRYPTO_TLS_CLOSE_NOTIFY                      TlsCloseNotify;
-  EDKII_CRYPTO_TLS_CTRL_TRAFFIC_OUT                  TlsCtrlTrafficOut;
-  EDKII_CRYPTO_TLS_CTRL_TRAFFIC_IN                   TlsCtrlTrafficIn;
-  EDKII_CRYPTO_TLS_READ                              TlsRead;
-  EDKII_CRYPTO_TLS_WRITE                             TlsWrite;
+  EDKII_CRYPTO_TLS_INITIALIZE                         TlsInitialize;
+  EDKII_CRYPTO_TLS_CTX_FREE                           TlsCtxFree;
+  EDKII_CRYPTO_TLS_CTX_NEW                            TlsCtxNew;
+  EDKII_CRYPTO_TLS_FREE                               TlsFree;
+  EDKII_CRYPTO_TLS_NEW                                TlsNew;
+  EDKII_CRYPTO_TLS_IN_HANDSHAKE                       TlsInHandshake;
+  EDKII_CRYPTO_TLS_DO_HANDSHAKE                       TlsDoHandshake;
+  EDKII_CRYPTO_TLS_HANDLE_ALERT                       TlsHandleAlert;
+  EDKII_CRYPTO_TLS_CLOSE_NOTIFY                       TlsCloseNotify;
+  EDKII_CRYPTO_TLS_CTRL_TRAFFIC_OUT                   TlsCtrlTrafficOut;
+  EDKII_CRYPTO_TLS_CTRL_TRAFFIC_IN                    TlsCtrlTrafficIn;
+  EDKII_CRYPTO_TLS_READ                               TlsRead;
+  EDKII_CRYPTO_TLS_WRITE                              TlsWrite;
   /// TLS Set
-  EDKII_CRYPTO_TLS_SET_VERSION                       TlsSetVersion;
-  EDKII_CRYPTO_TLS_SET_CONNECTION_END                TlsSetConnectionEnd;
-  EDKII_CRYPTO_TLS_SET_CIPHER_LIST                   TlsSetCipherList;
-  EDKII_CRYPTO_TLS_SET_COMPRESSION_METHOD            TlsSetCompressionMethod;
-  EDKII_CRYPTO_TLS_SET_VERIFY                        TlsSetVerify;
-  EDKII_CRYPTO_TLS_SET_VERIFY_HOST                   TlsSetVerifyHost;
-  EDKII_CRYPTO_TLS_SET_SESSIONID                     TlsSetSessionId;
-  EDKII_CRYPTO_TLS_SET_CA_CERTIFICATE                TlsSetCaCertificate;
-  EDKII_CRYPTO_TLS_SET_HOST_PUBLIC_CERT              TlsSetHostPublicCert;
-  EDKII_CRYPTO_TLS_SET_HOST_PRIVATE_KEY              TlsSetHostPrivateKey;
-  EDKII_CRYPTO_TLS_SET_CERT_REVOCATION_LIST          TlsSetCertRevocationList;
+  EDKII_CRYPTO_TLS_SET_VERSION                        TlsSetVersion;
+  EDKII_CRYPTO_TLS_SET_CONNECTION_END                 TlsSetConnectionEnd;
+  EDKII_CRYPTO_TLS_SET_CIPHER_LIST                    TlsSetCipherList;
+  EDKII_CRYPTO_TLS_SET_COMPRESSION_METHOD             TlsSetCompressionMethod;
+  EDKII_CRYPTO_TLS_SET_VERIFY                         TlsSetVerify;
+  EDKII_CRYPTO_TLS_SET_VERIFY_HOST                    TlsSetVerifyHost;
+  EDKII_CRYPTO_TLS_SET_SESSIONID                      TlsSetSessionId;
+  EDKII_CRYPTO_TLS_SET_CA_CERTIFICATE                 TlsSetCaCertificate;
+  EDKII_CRYPTO_TLS_SET_HOST_PUBLIC_CERT               TlsSetHostPublicCert;
+  EDKII_CRYPTO_TLS_SET_HOST_PRIVATE_KEY               TlsSetHostPrivateKey;
+  EDKII_CRYPTO_TLS_SET_CERT_REVOCATION_LIST           TlsSetCertRevocationList;
   /// TLS Get
-  EDKII_CRYPTO_TLS_GET_VERSION                       TlsGetVersion;
-  EDKII_CRYPTO_TLS_GET_CONNECTION_END                TlsGetConnectionEnd;
-  EDKII_CRYPTO_TLS_GET_CURRENT_CIPHER                TlsGetCurrentCipher;
-  EDKII_CRYPTO_TLS_GET_CURRENT_COMPRESSION_ID        TlsGetCurrentCompressionId;
-  EDKII_CRYPTO_TLS_GET_VERIFY                        TlsGetVerify;
-  EDKII_CRYPTO_TLS_GET_SESSION_ID                    TlsGetSessionId;
-  EDKII_CRYPTO_TLS_GET_CLIENT_RANDOM                 TlsGetClientRandom;
-  EDKII_CRYPTO_TLS_GET_SERVER_RANDOM                 TlsGetServerRandom;
-  EDKII_CRYPTO_TLS_GET_KEY_MATERIAL                  TlsGetKeyMaterial;
-  EDKII_CRYPTO_TLS_GET_CA_CERTIFICATE                TlsGetCaCertificate;
-  EDKII_CRYPTO_TLS_GET_HOST_PUBLIC_CERT              TlsGetHostPublicCert;
-  EDKII_CRYPTO_TLS_GET_HOST_PRIVATE_KEY              TlsGetHostPrivateKey;
-  EDKII_CRYPTO_TLS_GET_CERT_REVOCATION_LIST          TlsGetCertRevocationList;
+  EDKII_CRYPTO_TLS_GET_VERSION                        TlsGetVersion;
+  EDKII_CRYPTO_TLS_GET_CONNECTION_END                 TlsGetConnectionEnd;
+  EDKII_CRYPTO_TLS_GET_CURRENT_CIPHER                 TlsGetCurrentCipher;
+  EDKII_CRYPTO_TLS_GET_CURRENT_COMPRESSION_ID         TlsGetCurrentCompressionId;
+  EDKII_CRYPTO_TLS_GET_VERIFY                         TlsGetVerify;
+  EDKII_CRYPTO_TLS_GET_SESSION_ID                     TlsGetSessionId;
+  EDKII_CRYPTO_TLS_GET_CLIENT_RANDOM                  TlsGetClientRandom;
+  EDKII_CRYPTO_TLS_GET_SERVER_RANDOM                  TlsGetServerRandom;
+  EDKII_CRYPTO_TLS_GET_KEY_MATERIAL                   TlsGetKeyMaterial;
+  EDKII_CRYPTO_TLS_GET_CA_CERTIFICATE                 TlsGetCaCertificate;
+  EDKII_CRYPTO_TLS_GET_HOST_PUBLIC_CERT               TlsGetHostPublicCert;
+  EDKII_CRYPTO_TLS_GET_HOST_PRIVATE_KEY               TlsGetHostPrivateKey;
+  EDKII_CRYPTO_TLS_GET_CERT_REVOCATION_LIST           TlsGetCertRevocationList;
   /// RSA PSS
-  EDKII_CRYPTO_RSA_PSS_SIGN                          RsaPssSign;
-  EDKII_CRYPTO_RSA_PSS_VERIFY                        RsaPssVerify;
+  EDKII_CRYPTO_RSA_PSS_SIGN                           RsaPssSign;
+  EDKII_CRYPTO_RSA_PSS_VERIFY                         RsaPssVerify;
   /// Parallel hash
-  EDKII_CRYPTO_PARALLEL_HASH_ALL                     ParallelHash256HashAll;
+  EDKII_CRYPTO_PARALLEL_HASH_ALL                      ParallelHash256HashAll;
   /// HMAC SHA256 (continued)
-  EDKII_CRYPTO_HMAC_SHA256_ALL                       HmacSha256All;
+  EDKII_CRYPTO_HMAC_SHA256_ALL                        HmacSha256All;
   /// HMAC SHA384
-  EDKII_CRYPTO_HMAC_SHA384_NEW                       HmacSha384New;
-  EDKII_CRYPTO_HMAC_SHA384_FREE                      HmacSha384Free;
-  EDKII_CRYPTO_HMAC_SHA384_SET_KEY                   HmacSha384SetKey;
-  EDKII_CRYPTO_HMAC_SHA384_DUPLICATE                 HmacSha384Duplicate;
-  EDKII_CRYPTO_HMAC_SHA384_UPDATE                    HmacSha384Update;
-  EDKII_CRYPTO_HMAC_SHA384_FINAL                     HmacSha384Final;
-  EDKII_CRYPTO_HMAC_SHA384_ALL                       HmacSha384All;
+  EDKII_CRYPTO_HMAC_SHA384_NEW                        HmacSha384New;
+  EDKII_CRYPTO_HMAC_SHA384_FREE                       HmacSha384Free;
+  EDKII_CRYPTO_HMAC_SHA384_SET_KEY                    HmacSha384SetKey;
+  EDKII_CRYPTO_HMAC_SHA384_DUPLICATE                  HmacSha384Duplicate;
+  EDKII_CRYPTO_HMAC_SHA384_UPDATE                     HmacSha384Update;
+  EDKII_CRYPTO_HMAC_SHA384_FINAL                      HmacSha384Final;
+  EDKII_CRYPTO_HMAC_SHA384_ALL                        HmacSha384All;
   /// HKDF (continued)
-  EDKII_CRYPTO_HKDF_SHA_256_EXTRACT                  HkdfSha256Extract;
-  EDKII_CRYPTO_HKDF_SHA_256_EXPAND                   HkdfSha256Expand;
-  EDKII_CRYPTO_HKDF_SHA_384_EXTRACT_AND_EXPAND       HkdfSha384ExtractAndExpand;
-  EDKII_CRYPTO_HKDF_SHA_384_EXTRACT                  HkdfSha384Extract;
-  EDKII_CRYPTO_HKDF_SHA_384_EXPAND                   HkdfSha384Expand;
+  EDKII_CRYPTO_HKDF_SHA_256_EXTRACT                   HkdfSha256Extract;
+  EDKII_CRYPTO_HKDF_SHA_256_EXPAND                    HkdfSha256Expand;
+  EDKII_CRYPTO_HKDF_SHA_384_EXTRACT_AND_EXPAND        HkdfSha384ExtractAndExpand;
+  EDKII_CRYPTO_HKDF_SHA_384_EXTRACT                   HkdfSha384Extract;
+  EDKII_CRYPTO_HKDF_SHA_384_EXPAND                    HkdfSha384Expand;
   /// AEAD AES-GCM
-  EDKII_AEAD_AES_GCM_ENCRYPT                         AeadAesGcmEncrypt;
-  EDKII_AEAD_AES_GCM_DECRYPT                         AeadAesGcmDecrypt;
+  EDKII_AEAD_AES_GCM_ENCRYPT                          AeadAesGcmEncrypt;
+  EDKII_AEAD_AES_GCM_DECRYPT                          AeadAesGcmDecrypt;
   /// BIGNUM
-  EDKII_CRYPTO_BIGNUM_INIT                           BigNumInit;
-  EDKII_CRYPTO_BIGNUM_FROM_BIN                       BigNumFromBin;
-  EDKII_CRYPTO_BIGNUM_TO_BIN                         BigNumToBin;
-  EDKII_CRYPTO_BIGNUM_FREE                           BigNumFree;
-  EDKII_CRYPTO_BIGNUM_ADD                            BigNumAdd;
-  EDKII_CRYPTO_BIGNUM_SUB                            BigNumSub;
-  EDKII_CRYPTO_BIGNUM_MOD                            BigNumMod;
-  EDKII_CRYPTO_BIGNUM_EXP_MOD                        BigNumExpMod;
-  EDKII_CRYPTO_BIGNUM_INVERSE_MOD                    BigNumInverseMod;
-  EDKII_CRYPTO_BIGNUM_DIV                            BigNumDiv;
-  EDKII_CRYPTO_BIGNUM_MUL_MOD                        BigNumMulMod;
-  EDKII_CRYPTO_BIGNUM_CMP                            BigNumCmp;
-  EDKII_CRYPTO_BIGNUM_BITS                           BigNumBits;
-  EDKII_CRYPTO_BIGNUM_BYTES                          BigNumBytes;
-  EDKII_CRYPTO_BIGNUM_IS_WORD                        BigNumIsWord;
-  EDKII_CRYPTO_BIGNUM_IS_ODD                         BigNumIsOdd;
-  EDKII_CRYPTO_BIGNUM_COPY                           BigNumCopy;
-  EDKII_CRYPTO_BIGNUM_VALUE_ONE                      BigNumValueOne;
-  EDKII_CRYPTO_BIGNUM_R_SHIFT                        BigNumRShift;
-  EDKII_CRYPTO_BIGNUM_CONST_TIME                     BigNumConstTime;
-  EDKII_CRYPTO_BIGNUM_SQR_MOD                        BigNumSqrMod;
-  EDKII_CRYPTO_BIGNUM_NEW_CONTEXT                    BigNumNewContext;
-  EDKII_CRYPTO_BIGNUM_CONTEXT_FREE                   BigNumContextFree;
-  EDKII_CRYPTO_BIGNUM_SET_UINT                       BigNumSetUint;
-  EDKII_CRYPTO_BIGNUM_ADD_MOD                        BigNumAddMod;
+  EDKII_CRYPTO_BIGNUM_INIT                            BigNumInit;
+  EDKII_CRYPTO_BIGNUM_FROM_BIN                        BigNumFromBin;
+  EDKII_CRYPTO_BIGNUM_TO_BIN                          BigNumToBin;
+  EDKII_CRYPTO_BIGNUM_FREE                            BigNumFree;
+  EDKII_CRYPTO_BIGNUM_ADD                             BigNumAdd;
+  EDKII_CRYPTO_BIGNUM_SUB                             BigNumSub;
+  EDKII_CRYPTO_BIGNUM_MOD                             BigNumMod;
+  EDKII_CRYPTO_BIGNUM_EXP_MOD                         BigNumExpMod;
+  EDKII_CRYPTO_BIGNUM_INVERSE_MOD                     BigNumInverseMod;
+  EDKII_CRYPTO_BIGNUM_DIV                             BigNumDiv;
+  EDKII_CRYPTO_BIGNUM_MUL_MOD                         BigNumMulMod;
+  EDKII_CRYPTO_BIGNUM_CMP                             BigNumCmp;
+  EDKII_CRYPTO_BIGNUM_BITS                            BigNumBits;
+  EDKII_CRYPTO_BIGNUM_BYTES                           BigNumBytes;
+  EDKII_CRYPTO_BIGNUM_IS_WORD                         BigNumIsWord;
+  EDKII_CRYPTO_BIGNUM_IS_ODD                          BigNumIsOdd;
+  EDKII_CRYPTO_BIGNUM_COPY                            BigNumCopy;
+  EDKII_CRYPTO_BIGNUM_VALUE_ONE                       BigNumValueOne;
+  EDKII_CRYPTO_BIGNUM_R_SHIFT                         BigNumRShift;
+  EDKII_CRYPTO_BIGNUM_CONST_TIME                      BigNumConstTime;
+  EDKII_CRYPTO_BIGNUM_SQR_MOD                         BigNumSqrMod;
+  EDKII_CRYPTO_BIGNUM_NEW_CONTEXT                     BigNumNewContext;
+  EDKII_CRYPTO_BIGNUM_CONTEXT_FREE                    BigNumContextFree;
+  EDKII_CRYPTO_BIGNUM_SET_UINT                        BigNumSetUint;
+  EDKII_CRYPTO_BIGNUM_ADD_MOD                         BigNumAddMod;
+  /// X509 (Continued)
+  EDKII_CRYPTO_X509_GET_VERSION                       X509GetVersion;
+  EDKII_CRYPTO_X509_GET_SERIAL_NUMBER                 X509GetSerialNumber;
+  EDKII_CRYPTO_X509_GET_ISSUER_NAME                   X509GetIssuerName;
+  EDKII_CRYPTO_X509_GET_SIGNATURE_ALGORITHM           X509GetSignatureAlgorithm;
+  EDKII_CRYPTO_X509_GET_EXTENSION_DATA                X509GetExtensionData;
+  EDKII_CRYPTO_X509_GET_EXTENDED_KEY_USAGE            X509GetExtendedKeyUsage;
+  EDKII_CRYPTO_X509_GET_VALIDITY                      X509GetValidity;
+  EDKII_CRYPTO_X509_SET_DATE_TIME                     X509SetDateTime;
+  EDKII_CRYPTO_X509_COMPARE_DATE_TIME                 X509CompareDateTime;
+  EDKII_CRYPTO_X509_GET_KEY_USAGE                     X509GetKeyUsage;
+  EDKII_CRYPTO_X509_VERIFY_CERT_CHAIN                 X509VerifyCertChain;
+  EDKII_CRYPTO_X509_GET_CERT_FROM_CERT_CHAIN          X509GetCertFromCertChain;
+  EDKII_CRYPTO_ASN1_GET_TAG                           Asn1GetTag;
+  EDKII_CRYPTO_X509_GET_EXTENDED_BASIC_CONSTRAINTS    X509GetExtendedBasicConstraints;
 };
 
 extern GUID  gEdkiiCryptoProtocolGuid;
-- 
2.26.2.windows.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/4] CryptoPkg: add Unit Test for X509 new function.
  2022-09-25  8:54 [PATCH 0/4] CryptoPkg: add more X509 functions Qi Zhang
                   ` (2 preceding siblings ...)
  2022-09-25  8:54 ` [PATCH 3/4] CryptoPkg: add new X509 function to Crypto Service Qi Zhang
@ 2022-09-25  8:54 ` Qi Zhang
  3 siblings, 0 replies; 7+ messages in thread
From: Qi Zhang @ 2022-09-25  8:54 UTC (permalink / raw)
  To: devel; +Cc: Qi Zhang, Jiewen Yao, Jian J Wang, Xiaoyu Lu, Guomin Jiang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4082

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Signed-off-by: Qi Zhang <qi1.zhang@intel.com>
---
 .../BaseCryptLib/BaseCryptLibUnitTests.c      |   1 +
 .../Library/BaseCryptLib/TestBaseCryptLib.h   |   3 +
 .../BaseCryptLib/TestBaseCryptLibHost.inf     |   1 +
 .../BaseCryptLib/TestBaseCryptLibShell.inf    |   1 +
 .../UnitTest/Library/BaseCryptLib/X509Tests.c | 631 ++++++++++++++++++
 5 files changed, 637 insertions(+)
 create mode 100644 CryptoPkg/Test/UnitTest/Library/BaseCryptLib/X509Tests.c

diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
index 8450e95172..5afea59f29 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
@@ -28,6 +28,7 @@ SUITE_DESC  mSuiteDesc[] = {
   { "Hkdf extract and expand tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mHkdfTestNum,           mHkdfTest           },
   { "Aead AES Gcm tests",            "CryptoPkg.BaseCryptLib", NULL, NULL, &mAeadAesGcmTestNum,     mAeadAesGcmTest     },
   { "Bn verify tests",               "CryptoPkg.BaseCryptLib", NULL, NULL, &mBnTestNum,             mBnTest             },
+  { "X509 Verify tests",             "CryptoPkg.BaseCryptLib", NULL, NULL, &mX509TestNum,           mX509Test           },
 };
 
 EFI_STATUS
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
index fc44030ff6..173f260900 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
@@ -95,6 +95,9 @@ extern TEST_DESC  mAeadAesGcmTest[];
 extern UINTN      mBnTestNum;
 extern TEST_DESC  mBnTest[];
 
+extern UINTN      mX509TestNum;
+extern TEST_DESC  mX509Test[];
+
 /** Creates a framework you can use */
 EFI_STATUS
 EFIAPI
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
index 40dfade717..1785b46005 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
@@ -40,6 +40,7 @@
   HkdfTests.c
   AeadAesGcmTests.c
   BnTests.c
+  X509Tests.c
 
 [Packages]
   MdePkg/MdePkg.dec
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
index 00e6b088b8..70cdcf78f9 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
@@ -39,6 +39,7 @@
   HkdfTests.c
   AeadAesGcmTests.c
   BnTests.c
+  X509Tests.c
 
 [Packages]
   MdePkg/MdePkg.dec
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/X509Tests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/X509Tests.c
new file mode 100644
index 0000000000..d9e1f3066b
--- /dev/null
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/X509Tests.c
@@ -0,0 +1,631 @@
+/** @file
+  Application for X509 Cert Validation.
+
+Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "TestBaseCryptLib.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  mOidSubjectAltName[] = { 0x55, 0x1D, 0x11 };
+
+//
+// use openssl tool to create the test certificates.
+//
+// openssl req -nodes -x509 -days 3650 -newkey rsa:4096 -keyout ca.key -out ca.cert -sha256 -subj "/CN=intel test RSA CA"
+// openssl rsa -in ca.key -outform der -out ca.key.der
+// openssl req -nodes -newkey rsa:3072 -keyout inter.key -out inter.req -sha256 -batch -subj "/CN=intel test RSA intermediate cert"
+// openssl req -nodes -newkey rsa:2048 -keyout end_requester.key -out end_requester.req -sha256 -batch -subj "/CN=intel test RSA requseter cert"
+// openssl req -nodes -newkey rsa:2048 -keyout end_responder.key -out end_responder.req -sha256 -batch -subj "/CN=intel test RSA responder cert"
+// openssl x509 -req -in inter.req -out inter.cert -CA ca.cert -CAkey ca.key -sha256 -days 3650 -set_serial 1 -extensions v3_inter -extfile ../openssl.cnf
+// openssl x509 -req -in end_requester.req -out end_requester.cert -CA inter.cert -CAkey inter.key -sha256 -days 3650 -set_serial 2 -extensions v3_end -extfile ../openssl.cnf
+// openssl x509 -req -in end_responder.req -out end_responder.cert -CA inter.cert -CAkey inter.key -sha256 -days 3650 -set_serial 3 -extensions v3_end -extfile ../openssl.cnf
+// openssl asn1parse -in ca.cert -out ca.cert.der
+// openssl asn1parse -in inter.cert -out inter.cert.der
+// openssl asn1parse -in end_requester.cert -out end_requester.cert.der
+// cat ca.cert.der inter.cert.der end_requester.cert.der > bundle_requester.certchain.der
+// openssl rsa -inform PEM -outform DER -in end_requester.key -out end_requester.key.der
+//
+
+//
+// dump of inter.cert.der
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  mTestCert[] = {
+  0x30, 0x82, 0x04, 0xa0, 0x30, 0x82, 0x02, 0x88, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
+  0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x69, 0x6e, 0x74, 0x65,
+  0x6c, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17,
+  0x0d, 0x32, 0x32, 0x30, 0x31, 0x30, 0x35, 0x30, 0x36, 0x31, 0x31, 0x30, 0x36, 0x5a, 0x17, 0x0d,
+  0x33, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x36, 0x31, 0x31, 0x30, 0x36, 0x5a, 0x30, 0x2b, 0x31,
+  0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6c, 0x20,
+  0x74, 0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65,
+  0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x63, 0x65, 0x72, 0x74, 0x30, 0x82, 0x01, 0xa2, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+  0x8f, 0x00, 0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xd1, 0xcf, 0x2d, 0x21, 0x38,
+  0xe4, 0x81, 0xa6, 0xf2, 0xe5, 0xca, 0xac, 0x09, 0x2b, 0x04, 0x2a, 0x52, 0x76, 0x2f, 0xa3, 0x4b,
+  0x43, 0xc2, 0xd6, 0xb5, 0x3e, 0x2b, 0x29, 0x6f, 0x1b, 0x7d, 0x36, 0x60, 0xcd, 0x71, 0xf4, 0xcf,
+  0x8a, 0x24, 0xac, 0x8f, 0x5f, 0x78, 0x70, 0xc9, 0x84, 0x48, 0xfb, 0x1d, 0xcb, 0xee, 0x34, 0x3c,
+  0x4c, 0xe1, 0x1a, 0x92, 0x54, 0x43, 0x45, 0xe0, 0xdd, 0x14, 0xd5, 0xac, 0x13, 0xae, 0xcc, 0x45,
+  0xdc, 0x52, 0xdd, 0x45, 0x22, 0x10, 0xab, 0xb2, 0x1b, 0x3e, 0xad, 0x36, 0x6f, 0x00, 0x59, 0xb6,
+  0xfd, 0x27, 0xb8, 0x57, 0xbb, 0x66, 0x72, 0x1e, 0x7b, 0xe8, 0xc7, 0xaf, 0x5e, 0x65, 0x5c, 0x58,
+  0x3d, 0x9e, 0x78, 0x26, 0xb7, 0x70, 0x9a, 0xe7, 0x3c, 0xfc, 0x90, 0x64, 0xb2, 0xb2, 0xb2, 0x80,
+  0x22, 0xb3, 0x1c, 0x23, 0x73, 0x6a, 0xe3, 0xcb, 0x5b, 0x4e, 0x29, 0x71, 0xdd, 0xfd, 0xd7, 0x15,
+  0x3a, 0xd6, 0xa3, 0xe0, 0x4a, 0x53, 0x65, 0xa6, 0xae, 0x6a, 0x83, 0xb0, 0x00, 0x3f, 0x64, 0x4b,
+  0x01, 0xcd, 0x97, 0xb1, 0xe1, 0x54, 0x1e, 0xa2, 0x33, 0x4e, 0xf0, 0x13, 0x33, 0x80, 0xe5, 0x41,
+  0x9c, 0x5e, 0xb3, 0x5d, 0xae, 0x53, 0x2c, 0x41, 0x51, 0xf2, 0x00, 0x3e, 0x03, 0xe2, 0x0d, 0xa4,
+  0xf5, 0x24, 0x08, 0x46, 0xc2, 0xed, 0x6b, 0xf2, 0xe0, 0x1b, 0x04, 0xb7, 0xe8, 0xda, 0x85, 0xa4,
+  0x2f, 0x4b, 0x53, 0xfa, 0x76, 0x72, 0x0a, 0x28, 0xbf, 0x3c, 0xa8, 0x85, 0x03, 0xee, 0x51, 0xb5,
+  0x5c, 0xa9, 0xa5, 0x70, 0x47, 0x07, 0x11, 0x32, 0xc5, 0x5f, 0x7a, 0x07, 0xfb, 0x5f, 0x4a, 0x52,
+  0x65, 0x33, 0x0c, 0x17, 0x8e, 0x74, 0xe5, 0xec, 0x7d, 0x52, 0xa0, 0xd4, 0xef, 0x64, 0xcc, 0x5e,
+  0xe2, 0x3d, 0x46, 0x1e, 0x73, 0xab, 0x43, 0x2d, 0x05, 0xfa, 0xa3, 0x6d, 0x86, 0x02, 0xe7, 0xc8,
+  0x5f, 0x44, 0xfe, 0xeb, 0x14, 0x73, 0x2d, 0xf4, 0x0b, 0x72, 0x49, 0xe3, 0xef, 0x55, 0x05, 0x1b,
+  0x2f, 0xf9, 0x73, 0xeb, 0xed, 0xcc, 0x5e, 0x52, 0x17, 0x43, 0x94, 0x85, 0xc7, 0x0e, 0x73, 0x89,
+  0x22, 0xdc, 0x02, 0x5f, 0x99, 0x69, 0x58, 0x16, 0x89, 0x1e, 0x6f, 0x75, 0xf8, 0xd3, 0xe7, 0x0a,
+  0xb1, 0x01, 0x42, 0x71, 0xa6, 0xc5, 0xb2, 0xd0, 0xc0, 0x75, 0x96, 0x2e, 0xc2, 0x32, 0x49, 0x0a,
+  0xe8, 0x85, 0xbd, 0x22, 0x4c, 0x95, 0xd4, 0xf8, 0x2d, 0x72, 0x05, 0x4f, 0x0e, 0x56, 0x9c, 0xc3,
+  0x30, 0x3d, 0xfd, 0x30, 0x63, 0x92, 0x72, 0x6b, 0xaf, 0x80, 0x9d, 0xd0, 0xc2, 0x36, 0xe7, 0xc1,
+  0x37, 0xd0, 0x64, 0x88, 0x64, 0x3c, 0x33, 0xdd, 0x87, 0xdd, 0xd9, 0xa2, 0x79, 0x44, 0xd8, 0x25,
+  0x84, 0x0e, 0xfd, 0x9d, 0xd6, 0xc1, 0x7a, 0x2d, 0x23, 0x08, 0x9d, 0x02, 0x03, 0x01, 0x00, 0x01,
+  0xa3, 0x5e, 0x30, 0x5c, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01,
+  0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0xfe, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x46, 0xcd, 0xb4, 0x52, 0x02, 0x29,
+  0x26, 0xc7, 0x52, 0x23, 0x81, 0x65, 0xcd, 0x87, 0x2f, 0x96, 0x1b, 0x01, 0x2c, 0xc5, 0x30, 0x20,
+  0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
+  0x82, 0x02, 0x01, 0x00, 0x71, 0x14, 0xca, 0xfe, 0x03, 0x92, 0xc6, 0x88, 0x52, 0x76, 0x43, 0xd9,
+  0x8a, 0xf7, 0x22, 0x94, 0xef, 0x40, 0xa7, 0xc3, 0x7b, 0x6f, 0xb4, 0xd0, 0x42, 0xc3, 0x59, 0x1f,
+  0x77, 0xef, 0xac, 0x18, 0xce, 0x7c, 0xab, 0x48, 0x85, 0x22, 0xf1, 0x50, 0x2c, 0xe0, 0x63, 0x4d,
+  0x9d, 0x0e, 0xed, 0x38, 0xff, 0xd9, 0xed, 0x3c, 0x7e, 0x3e, 0x84, 0xb1, 0xa7, 0x78, 0x62, 0x37,
+  0x39, 0x6d, 0xd5, 0x5d, 0x46, 0x9a, 0x6f, 0x63, 0xc2, 0xa7, 0x90, 0xf9, 0x7a, 0xa7, 0x4b, 0xa2,
+  0x8a, 0xa8, 0x50, 0x13, 0x16, 0x9c, 0x4f, 0xcc, 0x28, 0x58, 0x6c, 0x9f, 0x65, 0x6e, 0xf0, 0x9a,
+  0x92, 0x59, 0x94, 0xa4, 0xb5, 0xfd, 0x8f, 0xf0, 0x7c, 0x1e, 0xba, 0xc3, 0x21, 0x13, 0xfb, 0x33,
+  0xba, 0xad, 0x4b, 0x1d, 0x42, 0x23, 0x16, 0x8b, 0x3e, 0xcd, 0xb5, 0x69, 0x9c, 0x7c, 0xa1, 0x9b,
+  0x92, 0xc1, 0x2f, 0x9c, 0x89, 0x3f, 0x28, 0x24, 0x67, 0x48, 0x47, 0xf0, 0xb1, 0xc0, 0xf0, 0x4c,
+  0xbf, 0xf6, 0x64, 0xde, 0x33, 0xc3, 0xd6, 0x5b, 0xe6, 0xc3, 0xdd, 0xa5, 0xba, 0x42, 0x02, 0x0f,
+  0xbc, 0xbe, 0xde, 0x14, 0x12, 0x7c, 0xfb, 0xe6, 0xbb, 0xdd, 0xf2, 0x6b, 0xd7, 0x75, 0xe6, 0xf5,
+  0xda, 0xbe, 0xe9, 0xbf, 0xa6, 0x87, 0x09, 0x41, 0x6c, 0x9d, 0x19, 0x9c, 0xb1, 0x7c, 0x89, 0x9f,
+  0x32, 0xb3, 0x0a, 0x59, 0x10, 0xc6, 0x8c, 0xa0, 0x5b, 0xda, 0xa6, 0xa3, 0xf8, 0x33, 0x77, 0x7a,
+  0xf4, 0xb0, 0x8a, 0xcf, 0xc8, 0x3f, 0x2e, 0xb8, 0xf1, 0x9e, 0x7b, 0x47, 0x2d, 0x85, 0x3b, 0x58,
+  0xcd, 0x4b, 0xbc, 0x87, 0xd2, 0xf3, 0xcd, 0x36, 0x80, 0x9b, 0x4a, 0x0f, 0x24, 0x30, 0x1d, 0x3f,
+  0x6f, 0x56, 0xcf, 0x6e, 0x2d, 0xcf, 0xa8, 0x17, 0xd5, 0x97, 0x0b, 0x22, 0xa6, 0x59, 0xef, 0xef,
+  0xd4, 0x9a, 0x0e, 0x6f, 0xb9, 0xf0, 0x48, 0x2a, 0x54, 0x22, 0x77, 0x27, 0x90, 0x84, 0x42, 0x56,
+  0x85, 0x80, 0x78, 0x4f, 0xd9, 0x14, 0x2a, 0xf0, 0x5d, 0x6b, 0x46, 0x60, 0x3d, 0xad, 0xa5, 0xa2,
+  0xb9, 0x04, 0x23, 0x92, 0x1b, 0x70, 0xa3, 0xdb, 0xaa, 0xf0, 0x5f, 0x1c, 0xd8, 0x26, 0xbb, 0x51,
+  0x17, 0xfc, 0x93, 0x6d, 0x70, 0x19, 0x54, 0xe2, 0x6f, 0x82, 0x8a, 0x49, 0xa6, 0x19, 0xcc, 0x97,
+  0x53, 0x90, 0x27, 0xd9, 0x8d, 0xaa, 0x8c, 0xc3, 0x2b, 0xbc, 0x0a, 0x72, 0x3a, 0x41, 0xb8, 0xfa,
+  0x1e, 0xbb, 0x8b, 0x27, 0x06, 0x75, 0x53, 0x91, 0xac, 0x8d, 0x75, 0xf2, 0xa6, 0xea, 0x85, 0x7e,
+  0x34, 0x06, 0x9e, 0xf9, 0xe9, 0x13, 0xa3, 0xfe, 0x2e, 0x38, 0x4b, 0x3f, 0x61, 0x11, 0x1f, 0x6b,
+  0xd3, 0xfe, 0xc9, 0x13, 0xbc, 0x12, 0xfe, 0xbc, 0xff, 0xaa, 0x38, 0x73, 0x8a, 0x73, 0x8c, 0xcf,
+  0xcc, 0xd3, 0xe7, 0xba, 0x98, 0xfd, 0xf4, 0xf5, 0xf6, 0xa9, 0xc8, 0x07, 0x5b, 0x16, 0xae, 0x76,
+  0x86, 0x24, 0x25, 0xcc, 0x7c, 0xdb, 0x1e, 0x7f, 0xc4, 0xe4, 0xd3, 0x89, 0x5a, 0x91, 0x6a, 0x9c,
+  0x93, 0x03, 0xd2, 0xd2, 0xc0, 0x29, 0x69, 0x58, 0x52, 0x6c, 0xca, 0x91, 0x7d, 0xd2, 0x3d, 0xc7,
+  0x2f, 0x8a, 0x4e, 0x55, 0x03, 0x34, 0x16, 0x01, 0x2f, 0x4f, 0x57, 0xea, 0x10, 0xa7, 0xfb, 0xe3,
+  0x2e, 0x2c, 0x7f, 0x5d, 0x27, 0x93, 0x74, 0x95, 0x25, 0x1a, 0x1e, 0x54, 0x1a, 0xb6, 0xe1, 0xdc,
+  0xc8, 0xe4, 0x84, 0xeb, 0x38, 0x0f, 0x05, 0x74, 0xf3, 0x3a, 0xf9, 0xd8, 0x00, 0x43, 0xe9, 0x24,
+  0x1e, 0x45, 0xb4, 0xe2, 0x38, 0x8b, 0x6a, 0x4f, 0xb6, 0x0b, 0x1d, 0xac, 0xbc, 0xec, 0xda, 0x41,
+  0x9c, 0x7f, 0xa8, 0x15, 0x09, 0x3b, 0x0b, 0x99, 0xc4, 0x48, 0xdd, 0xde, 0x0d, 0x65, 0x86, 0x72,
+  0xaa, 0x0a, 0x4e, 0x71,
+};
+
+//
+// dump of ca.cert.der
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  mTestCaCert[] = {
+  0x30, 0x82, 0x05, 0x19, 0x30, 0x82, 0x03, 0x01, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x1d,
+  0xaf, 0x4e, 0xf1, 0x99, 0xbf, 0xee, 0xe2, 0x6d, 0x7e, 0x4a, 0xac, 0xac, 0x20, 0x00, 0xeb, 0x78,
+  0xf6, 0x6a, 0xe9, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+  0x05, 0x00, 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x69,
+  0x6e, 0x74, 0x65, 0x6c, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x41,
+  0x30, 0x1e, 0x17, 0x0d, 0x32, 0x32, 0x30, 0x31, 0x30, 0x35, 0x30, 0x36, 0x31, 0x31, 0x30, 0x35,
+  0x5a, 0x17, 0x0d, 0x33, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x36, 0x31, 0x31, 0x30, 0x35, 0x5a,
+  0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x69, 0x6e, 0x74,
+  0x65, 0x6c, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x41, 0x30, 0x82,
+  0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+  0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xd5,
+  0x13, 0x55, 0xb1, 0x0d, 0x44, 0x17, 0x6a, 0x06, 0x39, 0x66, 0xee, 0xbc, 0x43, 0x81, 0xea, 0xe0,
+  0x93, 0x3f, 0x70, 0xb5, 0x5b, 0x07, 0xde, 0xa0, 0x24, 0x47, 0xd0, 0xf8, 0x99, 0xe6, 0x50, 0x17,
+  0xb4, 0x02, 0x60, 0xd9, 0x1a, 0x6c, 0xd3, 0x55, 0x60, 0x61, 0xde, 0x80, 0x6d, 0x38, 0x29, 0x46,
+  0xbb, 0x45, 0xa2, 0xeb, 0x24, 0x1c, 0xbb, 0x87, 0x1f, 0x14, 0xed, 0x3a, 0xd5, 0x32, 0xd5, 0x11,
+  0x4b, 0xf4, 0x99, 0x78, 0x00, 0x11, 0x8d, 0x6d, 0x6e, 0x5a, 0x0b, 0x81, 0xff, 0x08, 0x59, 0x01,
+  0x2b, 0xf0, 0x9b, 0x52, 0x88, 0x41, 0xb6, 0x3e, 0x62, 0x7b, 0xbd, 0x25, 0x96, 0x64, 0x8e, 0xb1,
+  0x2b, 0x6a, 0xf8, 0x39, 0x93, 0x0a, 0x6b, 0x3f, 0x8c, 0x2b, 0x35, 0x6e, 0x80, 0x32, 0x86, 0xf6,
+  0x0f, 0x1e, 0x8c, 0xd4, 0x4e, 0x77, 0xbe, 0xaf, 0xe5, 0x4c, 0x47, 0x66, 0xdd, 0x62, 0xce, 0x64,
+  0x65, 0x80, 0xca, 0xbd, 0x87, 0x94, 0x3e, 0xff, 0x3d, 0x0a, 0xd4, 0x39, 0xcc, 0xd1, 0xef, 0xd1,
+  0x1a, 0x55, 0x2c, 0xeb, 0xdc, 0xcf, 0x9a, 0x59, 0x92, 0xda, 0xca, 0xf6, 0xae, 0x88, 0xbc, 0xc0,
+  0x43, 0xe5, 0xa9, 0x60, 0xb2, 0x0f, 0x69, 0xa2, 0x2a, 0x98, 0x56, 0x0f, 0x4b, 0x0b, 0x63, 0xb3,
+  0x4e, 0x8b, 0x43, 0xb4, 0x7f, 0x52, 0x1e, 0x5a, 0x9e, 0xdf, 0xa7, 0x98, 0x4d, 0xb9, 0x3b, 0x58,
+  0x80, 0x69, 0x38, 0xb7, 0xeb, 0x20, 0x91, 0xbf, 0x59, 0x81, 0x44, 0xfc, 0xc6, 0xaf, 0xc2, 0xc8,
+  0xe1, 0xae, 0x3d, 0xc5, 0xb6, 0x55, 0xa8, 0xa2, 0xcd, 0xec, 0x0b, 0xbe, 0x9c, 0x34, 0x2b, 0xf5,
+  0x4b, 0x2e, 0x3b, 0x26, 0xaa, 0x22, 0x12, 0x29, 0xc2, 0x66, 0xc2, 0x40, 0xdd, 0x12, 0xfa, 0xf0,
+  0xb4, 0xe8, 0x95, 0x20, 0x59, 0x91, 0x9e, 0x7d, 0x36, 0x6e, 0x2d, 0x99, 0x53, 0x44, 0x2b, 0x43,
+  0x12, 0x08, 0x74, 0x76, 0xd5, 0x21, 0xd3, 0x08, 0x37, 0xe1, 0xe6, 0xe3, 0xc4, 0x67, 0x88, 0x29,
+  0xea, 0x06, 0x97, 0x9f, 0x61, 0x0d, 0x5d, 0x39, 0x17, 0x03, 0x87, 0x89, 0x35, 0xe0, 0xd5, 0x87,
+  0xa1, 0x5b, 0x0c, 0x3c, 0x35, 0x3d, 0xd6, 0x6f, 0xdd, 0x6f, 0xa5, 0x11, 0x9f, 0x80, 0x20, 0xca,
+  0x8b, 0x67, 0xd2, 0x2c, 0x7c, 0x51, 0x68, 0x15, 0x2c, 0x9c, 0x08, 0x86, 0xc8, 0x6c, 0xf0, 0x9d,
+  0xc2, 0x98, 0xb9, 0x6e, 0x31, 0xaf, 0x2b, 0x34, 0x9c, 0xe3, 0xd0, 0xe9, 0x85, 0x37, 0x2b, 0x1f,
+  0x21, 0xd2, 0xb9, 0xa4, 0x8d, 0x3f, 0xa3, 0x1a, 0x9f, 0x7d, 0x1b, 0xb6, 0xe0, 0xf6, 0x19, 0xf4,
+  0x19, 0xf8, 0x50, 0xa7, 0x1b, 0xec, 0xb9, 0xbb, 0xa4, 0xd2, 0x20, 0xf3, 0xed, 0xc7, 0xa7, 0x94,
+  0x2b, 0x0b, 0x9a, 0x74, 0xb8, 0xba, 0xd7, 0x42, 0x97, 0xab, 0xb4, 0xe9, 0xbe, 0x1e, 0x07, 0x0c,
+  0x05, 0x55, 0x54, 0xba, 0x05, 0x73, 0x99, 0xf2, 0x29, 0x88, 0x69, 0x4f, 0x1b, 0x2e, 0x87, 0x7b,
+  0x74, 0x94, 0xae, 0xc2, 0x2f, 0x3c, 0x90, 0xb5, 0x5c, 0x01, 0x46, 0xc6, 0x42, 0xfb, 0xa9, 0xad,
+  0x82, 0x1b, 0xd9, 0x38, 0xbe, 0x0d, 0x72, 0x4c, 0x06, 0x03, 0x92, 0xc2, 0xc8, 0x7f, 0x7b, 0xd4,
+  0x86, 0x83, 0xb8, 0x62, 0xd9, 0xf7, 0x2f, 0xc1, 0x57, 0x88, 0x85, 0xa5, 0x61, 0xc5, 0x93, 0xfc,
+  0x17, 0xe0, 0x98, 0x11, 0x88, 0x0d, 0x03, 0x0b, 0x6e, 0x01, 0x16, 0xcc, 0xf2, 0x3c, 0x5f, 0x61,
+  0x8c, 0x27, 0x31, 0xca, 0x4d, 0x35, 0x7a, 0xc1, 0xf3, 0xfe, 0x06, 0xff, 0xca, 0x7b, 0x96, 0xad,
+  0x0d, 0xff, 0x9e, 0x12, 0x44, 0x51, 0x6e, 0xf4, 0xaa, 0x2e, 0xce, 0xe8, 0xc7, 0xa6, 0xe9, 0xae,
+  0xc0, 0xbe, 0xde, 0x7b, 0x93, 0x3d, 0x1d, 0xf9, 0xfb, 0x4d, 0xa7, 0x0b, 0x73, 0xfb, 0x7b, 0x02,
+  0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+  0x16, 0x04, 0x14, 0x03, 0xfe, 0xb0, 0x3f, 0x09, 0xe5, 0xe1, 0xf4, 0x2e, 0x87, 0xfb, 0x41, 0x86,
+  0xf6, 0x76, 0xd3, 0x93, 0xbe, 0x96, 0x85, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+  0x30, 0x16, 0x80, 0x14, 0x03, 0xfe, 0xb0, 0x3f, 0x09, 0xe5, 0xe1, 0xf4, 0x2e, 0x87, 0xfb, 0x41,
+  0x86, 0xf6, 0x76, 0xd3, 0x93, 0xbe, 0x96, 0x85, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+  0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x02, 0x15, 0x73,
+  0x60, 0x10, 0xbc, 0x95, 0xac, 0x63, 0x15, 0x09, 0x6b, 0x0c, 0x09, 0x4a, 0x74, 0xcd, 0xe3, 0x58,
+  0xcc, 0x6c, 0xf3, 0x55, 0x80, 0xe9, 0x75, 0x47, 0x2c, 0x80, 0x4e, 0x5f, 0xfe, 0xbd, 0x2e, 0xd7,
+  0x42, 0x89, 0x44, 0x57, 0xbe, 0x51, 0x84, 0x53, 0xb6, 0x40, 0x80, 0xd6, 0xcc, 0xe2, 0x80, 0x22,
+  0x53, 0xd9, 0x31, 0x65, 0xf9, 0x3c, 0x8b, 0x7b, 0xe6, 0xa6, 0x6e, 0xfd, 0x9d, 0x27, 0xe5, 0xcd,
+  0xfd, 0x82, 0xcf, 0xd6, 0x18, 0xbe, 0xa6, 0xed, 0x72, 0xce, 0x5f, 0x45, 0x12, 0x6a, 0xaa, 0x95,
+  0x42, 0x25, 0x28, 0x8b, 0xfc, 0x4b, 0xc9, 0xad, 0xdd, 0xdb, 0x4c, 0x74, 0x10, 0x2e, 0x90, 0x2a,
+  0x06, 0x4f, 0x2e, 0xb4, 0x54, 0xb9, 0xc0, 0x60, 0xb9, 0x4d, 0xee, 0x59, 0x1c, 0x18, 0x8d, 0xd1,
+  0x49, 0xc3, 0xe9, 0x1b, 0xf1, 0xfc, 0xc3, 0x83, 0x1f, 0x6a, 0xb0, 0xfc, 0x8d, 0xfc, 0x30, 0xed,
+  0x9c, 0xcb, 0x78, 0x52, 0xe8, 0x09, 0x3d, 0x4f, 0xdc, 0xbc, 0xad, 0x84, 0xc1, 0xd5, 0x5a, 0x0a,
+  0x07, 0xa3, 0xf6, 0x42, 0xd7, 0x54, 0x55, 0x01, 0x8e, 0x53, 0xce, 0xcb, 0x2a, 0x11, 0xf7, 0x89,
+  0x7e, 0xaf, 0x6f, 0x4c, 0xb9, 0x56, 0x4a, 0x67, 0x4a, 0xf9, 0x4f, 0x64, 0x15, 0xfa, 0xb0, 0xf9,
+  0x97, 0xe2, 0xf6, 0xa8, 0xf4, 0xe7, 0x0a, 0x7a, 0x83, 0x4e, 0xf6, 0xe9, 0xac, 0x5e, 0xd9, 0xa8,
+  0xea, 0x6b, 0x06, 0xcb, 0x2c, 0x41, 0xc1, 0x7e, 0xf5, 0x79, 0xfc, 0x7c, 0x05, 0x06, 0x8f, 0x27,
+  0xaa, 0x3b, 0x61, 0x82, 0x72, 0x55, 0xa9, 0xa0, 0xa0, 0xa5, 0x69, 0x2f, 0x95, 0x40, 0xfc, 0xfe,
+  0x4a, 0x0f, 0x7d, 0x8c, 0x89, 0xaa, 0xc0, 0x1d, 0x87, 0x03, 0xa1, 0xce, 0xee, 0x23, 0x4f, 0xc5,
+  0x7c, 0xb4, 0xb6, 0x2b, 0x6f, 0x05, 0x30, 0xc9, 0x16, 0x51, 0xdf, 0xc7, 0x16, 0x3c, 0x08, 0x38,
+  0x20, 0xf9, 0xc5, 0xe0, 0x4a, 0xfa, 0xcb, 0x8c, 0xc3, 0xc5, 0xbb, 0x5c, 0xad, 0xca, 0xc2, 0x52,
+  0x45, 0x2f, 0x54, 0x70, 0x78, 0x33, 0x70, 0xc2, 0xed, 0x68, 0xf1, 0x89, 0x67, 0xa3, 0x19, 0x24,
+  0xcb, 0x8f, 0x99, 0x1b, 0x28, 0x81, 0x6c, 0x4e, 0x25, 0xb1, 0x27, 0x3d, 0x9f, 0xe7, 0x3d, 0xa7,
+  0x73, 0x9e, 0x4c, 0x1a, 0x63, 0x8e, 0xf9, 0xa7, 0xb6, 0x21, 0xe7, 0x4c, 0xdf, 0xfb, 0x36, 0x47,
+  0xda, 0x2d, 0xbb, 0x52, 0x55, 0xf8, 0x44, 0x0d, 0x0c, 0xde, 0xe2, 0x13, 0x42, 0x1b, 0xa2, 0xad,
+  0xa0, 0x0f, 0x39, 0x6c, 0x78, 0x32, 0x7a, 0x03, 0x9e, 0x55, 0x4e, 0x43, 0xf7, 0x0c, 0x35, 0xd9,
+  0x1d, 0x2c, 0x0f, 0x30, 0x30, 0x3e, 0x09, 0xe2, 0x31, 0xa6, 0xb0, 0x1e, 0xa9, 0xf5, 0x4b, 0xa1,
+  0x74, 0x09, 0x50, 0xd4, 0xd3, 0xd3, 0x3e, 0x76, 0xb1, 0x67, 0xfc, 0x51, 0xb0, 0x93, 0x22, 0xc4,
+  0x6b, 0x8a, 0x27, 0x45, 0x19, 0x3b, 0x35, 0x91, 0x61, 0x36, 0xe7, 0x9c, 0xf6, 0xda, 0x96, 0x30,
+  0x7d, 0xf4, 0x11, 0xc4, 0x3f, 0x35, 0x4e, 0x7a, 0xd6, 0x6e, 0xb6, 0xea, 0xe7, 0x66, 0x6f, 0x23,
+  0x5c, 0x53, 0x76, 0x53, 0xfc, 0x35, 0x93, 0xe5, 0xfc, 0xb9, 0x6b, 0xb9, 0xd3, 0x6c, 0x48, 0x66,
+  0x6f, 0xd7, 0x10, 0x6e, 0x25, 0x72, 0x71, 0x31, 0xfa, 0xc0, 0xdf, 0x31, 0xca, 0xd1, 0xaf, 0xc2,
+  0x8e, 0xa5, 0xca, 0xd7, 0x3f, 0x4e, 0xde, 0x47, 0xd5, 0x8e, 0xfc, 0x75, 0xb6, 0x71, 0x83, 0xd9,
+  0xfd, 0x11, 0x35, 0x81, 0xbf, 0x10, 0x0d, 0x3e, 0x50, 0x45, 0x07, 0x39, 0x08, 0x73, 0x7a, 0x0b,
+  0x21, 0x32, 0xaf, 0xf4, 0x99, 0xeb, 0x4d, 0xd4, 0xe8, 0x2a, 0x06, 0x98, 0x43, 0xbb, 0xbb, 0x11,
+  0x63, 0x99, 0xa8, 0x41, 0x22, 0xe8, 0x86, 0x79, 0x4b, 0x53, 0xb7, 0x73, 0x1b,
+};
+
+//
+// dump of bundle_requester.certchain.der
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  mTestBundleCert[] = {
+  0x30, 0x82, 0x05, 0x19, 0x30, 0x82, 0x03, 0x01, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x1d,
+  0xaf, 0x4e, 0xf1, 0x99, 0xbf, 0xee, 0xe2, 0x6d, 0x7e, 0x4a, 0xac, 0xac, 0x20, 0x00, 0xeb, 0x78,
+  0xf6, 0x6a, 0xe9, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+  0x05, 0x00, 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x69,
+  0x6e, 0x74, 0x65, 0x6c, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x41,
+  0x30, 0x1e, 0x17, 0x0d, 0x32, 0x32, 0x30, 0x31, 0x30, 0x35, 0x30, 0x36, 0x31, 0x31, 0x30, 0x35,
+  0x5a, 0x17, 0x0d, 0x33, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x36, 0x31, 0x31, 0x30, 0x35, 0x5a,
+  0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x69, 0x6e, 0x74,
+  0x65, 0x6c, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x41, 0x30, 0x82,
+  0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+  0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xd5,
+  0x13, 0x55, 0xb1, 0x0d, 0x44, 0x17, 0x6a, 0x06, 0x39, 0x66, 0xee, 0xbc, 0x43, 0x81, 0xea, 0xe0,
+  0x93, 0x3f, 0x70, 0xb5, 0x5b, 0x07, 0xde, 0xa0, 0x24, 0x47, 0xd0, 0xf8, 0x99, 0xe6, 0x50, 0x17,
+  0xb4, 0x02, 0x60, 0xd9, 0x1a, 0x6c, 0xd3, 0x55, 0x60, 0x61, 0xde, 0x80, 0x6d, 0x38, 0x29, 0x46,
+  0xbb, 0x45, 0xa2, 0xeb, 0x24, 0x1c, 0xbb, 0x87, 0x1f, 0x14, 0xed, 0x3a, 0xd5, 0x32, 0xd5, 0x11,
+  0x4b, 0xf4, 0x99, 0x78, 0x00, 0x11, 0x8d, 0x6d, 0x6e, 0x5a, 0x0b, 0x81, 0xff, 0x08, 0x59, 0x01,
+  0x2b, 0xf0, 0x9b, 0x52, 0x88, 0x41, 0xb6, 0x3e, 0x62, 0x7b, 0xbd, 0x25, 0x96, 0x64, 0x8e, 0xb1,
+  0x2b, 0x6a, 0xf8, 0x39, 0x93, 0x0a, 0x6b, 0x3f, 0x8c, 0x2b, 0x35, 0x6e, 0x80, 0x32, 0x86, 0xf6,
+  0x0f, 0x1e, 0x8c, 0xd4, 0x4e, 0x77, 0xbe, 0xaf, 0xe5, 0x4c, 0x47, 0x66, 0xdd, 0x62, 0xce, 0x64,
+  0x65, 0x80, 0xca, 0xbd, 0x87, 0x94, 0x3e, 0xff, 0x3d, 0x0a, 0xd4, 0x39, 0xcc, 0xd1, 0xef, 0xd1,
+  0x1a, 0x55, 0x2c, 0xeb, 0xdc, 0xcf, 0x9a, 0x59, 0x92, 0xda, 0xca, 0xf6, 0xae, 0x88, 0xbc, 0xc0,
+  0x43, 0xe5, 0xa9, 0x60, 0xb2, 0x0f, 0x69, 0xa2, 0x2a, 0x98, 0x56, 0x0f, 0x4b, 0x0b, 0x63, 0xb3,
+  0x4e, 0x8b, 0x43, 0xb4, 0x7f, 0x52, 0x1e, 0x5a, 0x9e, 0xdf, 0xa7, 0x98, 0x4d, 0xb9, 0x3b, 0x58,
+  0x80, 0x69, 0x38, 0xb7, 0xeb, 0x20, 0x91, 0xbf, 0x59, 0x81, 0x44, 0xfc, 0xc6, 0xaf, 0xc2, 0xc8,
+  0xe1, 0xae, 0x3d, 0xc5, 0xb6, 0x55, 0xa8, 0xa2, 0xcd, 0xec, 0x0b, 0xbe, 0x9c, 0x34, 0x2b, 0xf5,
+  0x4b, 0x2e, 0x3b, 0x26, 0xaa, 0x22, 0x12, 0x29, 0xc2, 0x66, 0xc2, 0x40, 0xdd, 0x12, 0xfa, 0xf0,
+  0xb4, 0xe8, 0x95, 0x20, 0x59, 0x91, 0x9e, 0x7d, 0x36, 0x6e, 0x2d, 0x99, 0x53, 0x44, 0x2b, 0x43,
+  0x12, 0x08, 0x74, 0x76, 0xd5, 0x21, 0xd3, 0x08, 0x37, 0xe1, 0xe6, 0xe3, 0xc4, 0x67, 0x88, 0x29,
+  0xea, 0x06, 0x97, 0x9f, 0x61, 0x0d, 0x5d, 0x39, 0x17, 0x03, 0x87, 0x89, 0x35, 0xe0, 0xd5, 0x87,
+  0xa1, 0x5b, 0x0c, 0x3c, 0x35, 0x3d, 0xd6, 0x6f, 0xdd, 0x6f, 0xa5, 0x11, 0x9f, 0x80, 0x20, 0xca,
+  0x8b, 0x67, 0xd2, 0x2c, 0x7c, 0x51, 0x68, 0x15, 0x2c, 0x9c, 0x08, 0x86, 0xc8, 0x6c, 0xf0, 0x9d,
+  0xc2, 0x98, 0xb9, 0x6e, 0x31, 0xaf, 0x2b, 0x34, 0x9c, 0xe3, 0xd0, 0xe9, 0x85, 0x37, 0x2b, 0x1f,
+  0x21, 0xd2, 0xb9, 0xa4, 0x8d, 0x3f, 0xa3, 0x1a, 0x9f, 0x7d, 0x1b, 0xb6, 0xe0, 0xf6, 0x19, 0xf4,
+  0x19, 0xf8, 0x50, 0xa7, 0x1b, 0xec, 0xb9, 0xbb, 0xa4, 0xd2, 0x20, 0xf3, 0xed, 0xc7, 0xa7, 0x94,
+  0x2b, 0x0b, 0x9a, 0x74, 0xb8, 0xba, 0xd7, 0x42, 0x97, 0xab, 0xb4, 0xe9, 0xbe, 0x1e, 0x07, 0x0c,
+  0x05, 0x55, 0x54, 0xba, 0x05, 0x73, 0x99, 0xf2, 0x29, 0x88, 0x69, 0x4f, 0x1b, 0x2e, 0x87, 0x7b,
+  0x74, 0x94, 0xae, 0xc2, 0x2f, 0x3c, 0x90, 0xb5, 0x5c, 0x01, 0x46, 0xc6, 0x42, 0xfb, 0xa9, 0xad,
+  0x82, 0x1b, 0xd9, 0x38, 0xbe, 0x0d, 0x72, 0x4c, 0x06, 0x03, 0x92, 0xc2, 0xc8, 0x7f, 0x7b, 0xd4,
+  0x86, 0x83, 0xb8, 0x62, 0xd9, 0xf7, 0x2f, 0xc1, 0x57, 0x88, 0x85, 0xa5, 0x61, 0xc5, 0x93, 0xfc,
+  0x17, 0xe0, 0x98, 0x11, 0x88, 0x0d, 0x03, 0x0b, 0x6e, 0x01, 0x16, 0xcc, 0xf2, 0x3c, 0x5f, 0x61,
+  0x8c, 0x27, 0x31, 0xca, 0x4d, 0x35, 0x7a, 0xc1, 0xf3, 0xfe, 0x06, 0xff, 0xca, 0x7b, 0x96, 0xad,
+  0x0d, 0xff, 0x9e, 0x12, 0x44, 0x51, 0x6e, 0xf4, 0xaa, 0x2e, 0xce, 0xe8, 0xc7, 0xa6, 0xe9, 0xae,
+  0xc0, 0xbe, 0xde, 0x7b, 0x93, 0x3d, 0x1d, 0xf9, 0xfb, 0x4d, 0xa7, 0x0b, 0x73, 0xfb, 0x7b, 0x02,
+  0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+  0x16, 0x04, 0x14, 0x03, 0xfe, 0xb0, 0x3f, 0x09, 0xe5, 0xe1, 0xf4, 0x2e, 0x87, 0xfb, 0x41, 0x86,
+  0xf6, 0x76, 0xd3, 0x93, 0xbe, 0x96, 0x85, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+  0x30, 0x16, 0x80, 0x14, 0x03, 0xfe, 0xb0, 0x3f, 0x09, 0xe5, 0xe1, 0xf4, 0x2e, 0x87, 0xfb, 0x41,
+  0x86, 0xf6, 0x76, 0xd3, 0x93, 0xbe, 0x96, 0x85, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+  0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x02, 0x15, 0x73,
+  0x60, 0x10, 0xbc, 0x95, 0xac, 0x63, 0x15, 0x09, 0x6b, 0x0c, 0x09, 0x4a, 0x74, 0xcd, 0xe3, 0x58,
+  0xcc, 0x6c, 0xf3, 0x55, 0x80, 0xe9, 0x75, 0x47, 0x2c, 0x80, 0x4e, 0x5f, 0xfe, 0xbd, 0x2e, 0xd7,
+  0x42, 0x89, 0x44, 0x57, 0xbe, 0x51, 0x84, 0x53, 0xb6, 0x40, 0x80, 0xd6, 0xcc, 0xe2, 0x80, 0x22,
+  0x53, 0xd9, 0x31, 0x65, 0xf9, 0x3c, 0x8b, 0x7b, 0xe6, 0xa6, 0x6e, 0xfd, 0x9d, 0x27, 0xe5, 0xcd,
+  0xfd, 0x82, 0xcf, 0xd6, 0x18, 0xbe, 0xa6, 0xed, 0x72, 0xce, 0x5f, 0x45, 0x12, 0x6a, 0xaa, 0x95,
+  0x42, 0x25, 0x28, 0x8b, 0xfc, 0x4b, 0xc9, 0xad, 0xdd, 0xdb, 0x4c, 0x74, 0x10, 0x2e, 0x90, 0x2a,
+  0x06, 0x4f, 0x2e, 0xb4, 0x54, 0xb9, 0xc0, 0x60, 0xb9, 0x4d, 0xee, 0x59, 0x1c, 0x18, 0x8d, 0xd1,
+  0x49, 0xc3, 0xe9, 0x1b, 0xf1, 0xfc, 0xc3, 0x83, 0x1f, 0x6a, 0xb0, 0xfc, 0x8d, 0xfc, 0x30, 0xed,
+  0x9c, 0xcb, 0x78, 0x52, 0xe8, 0x09, 0x3d, 0x4f, 0xdc, 0xbc, 0xad, 0x84, 0xc1, 0xd5, 0x5a, 0x0a,
+  0x07, 0xa3, 0xf6, 0x42, 0xd7, 0x54, 0x55, 0x01, 0x8e, 0x53, 0xce, 0xcb, 0x2a, 0x11, 0xf7, 0x89,
+  0x7e, 0xaf, 0x6f, 0x4c, 0xb9, 0x56, 0x4a, 0x67, 0x4a, 0xf9, 0x4f, 0x64, 0x15, 0xfa, 0xb0, 0xf9,
+  0x97, 0xe2, 0xf6, 0xa8, 0xf4, 0xe7, 0x0a, 0x7a, 0x83, 0x4e, 0xf6, 0xe9, 0xac, 0x5e, 0xd9, 0xa8,
+  0xea, 0x6b, 0x06, 0xcb, 0x2c, 0x41, 0xc1, 0x7e, 0xf5, 0x79, 0xfc, 0x7c, 0x05, 0x06, 0x8f, 0x27,
+  0xaa, 0x3b, 0x61, 0x82, 0x72, 0x55, 0xa9, 0xa0, 0xa0, 0xa5, 0x69, 0x2f, 0x95, 0x40, 0xfc, 0xfe,
+  0x4a, 0x0f, 0x7d, 0x8c, 0x89, 0xaa, 0xc0, 0x1d, 0x87, 0x03, 0xa1, 0xce, 0xee, 0x23, 0x4f, 0xc5,
+  0x7c, 0xb4, 0xb6, 0x2b, 0x6f, 0x05, 0x30, 0xc9, 0x16, 0x51, 0xdf, 0xc7, 0x16, 0x3c, 0x08, 0x38,
+  0x20, 0xf9, 0xc5, 0xe0, 0x4a, 0xfa, 0xcb, 0x8c, 0xc3, 0xc5, 0xbb, 0x5c, 0xad, 0xca, 0xc2, 0x52,
+  0x45, 0x2f, 0x54, 0x70, 0x78, 0x33, 0x70, 0xc2, 0xed, 0x68, 0xf1, 0x89, 0x67, 0xa3, 0x19, 0x24,
+  0xcb, 0x8f, 0x99, 0x1b, 0x28, 0x81, 0x6c, 0x4e, 0x25, 0xb1, 0x27, 0x3d, 0x9f, 0xe7, 0x3d, 0xa7,
+  0x73, 0x9e, 0x4c, 0x1a, 0x63, 0x8e, 0xf9, 0xa7, 0xb6, 0x21, 0xe7, 0x4c, 0xdf, 0xfb, 0x36, 0x47,
+  0xda, 0x2d, 0xbb, 0x52, 0x55, 0xf8, 0x44, 0x0d, 0x0c, 0xde, 0xe2, 0x13, 0x42, 0x1b, 0xa2, 0xad,
+  0xa0, 0x0f, 0x39, 0x6c, 0x78, 0x32, 0x7a, 0x03, 0x9e, 0x55, 0x4e, 0x43, 0xf7, 0x0c, 0x35, 0xd9,
+  0x1d, 0x2c, 0x0f, 0x30, 0x30, 0x3e, 0x09, 0xe2, 0x31, 0xa6, 0xb0, 0x1e, 0xa9, 0xf5, 0x4b, 0xa1,
+  0x74, 0x09, 0x50, 0xd4, 0xd3, 0xd3, 0x3e, 0x76, 0xb1, 0x67, 0xfc, 0x51, 0xb0, 0x93, 0x22, 0xc4,
+  0x6b, 0x8a, 0x27, 0x45, 0x19, 0x3b, 0x35, 0x91, 0x61, 0x36, 0xe7, 0x9c, 0xf6, 0xda, 0x96, 0x30,
+  0x7d, 0xf4, 0x11, 0xc4, 0x3f, 0x35, 0x4e, 0x7a, 0xd6, 0x6e, 0xb6, 0xea, 0xe7, 0x66, 0x6f, 0x23,
+  0x5c, 0x53, 0x76, 0x53, 0xfc, 0x35, 0x93, 0xe5, 0xfc, 0xb9, 0x6b, 0xb9, 0xd3, 0x6c, 0x48, 0x66,
+  0x6f, 0xd7, 0x10, 0x6e, 0x25, 0x72, 0x71, 0x31, 0xfa, 0xc0, 0xdf, 0x31, 0xca, 0xd1, 0xaf, 0xc2,
+  0x8e, 0xa5, 0xca, 0xd7, 0x3f, 0x4e, 0xde, 0x47, 0xd5, 0x8e, 0xfc, 0x75, 0xb6, 0x71, 0x83, 0xd9,
+  0xfd, 0x11, 0x35, 0x81, 0xbf, 0x10, 0x0d, 0x3e, 0x50, 0x45, 0x07, 0x39, 0x08, 0x73, 0x7a, 0x0b,
+  0x21, 0x32, 0xaf, 0xf4, 0x99, 0xeb, 0x4d, 0xd4, 0xe8, 0x2a, 0x06, 0x98, 0x43, 0xbb, 0xbb, 0x11,
+  0x63, 0x99, 0xa8, 0x41, 0x22, 0xe8, 0x86, 0x79, 0x4b, 0x53, 0xb7, 0x73, 0x1b, 0x30, 0x82, 0x04,
+  0xa0, 0x30, 0x82, 0x02, 0x88, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x1c, 0x31, 0x1a,
+  0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x69, 0x6e, 0x74, 0x65, 0x6c, 0x20, 0x74,
+  0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x32,
+  0x30, 0x31, 0x30, 0x35, 0x30, 0x36, 0x31, 0x31, 0x30, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x32, 0x30,
+  0x31, 0x30, 0x33, 0x30, 0x36, 0x31, 0x31, 0x30, 0x36, 0x5a, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x27,
+  0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6c, 0x20, 0x74, 0x65, 0x73,
+  0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61,
+  0x74, 0x65, 0x20, 0x63, 0x65, 0x72, 0x74, 0x30, 0x82, 0x01, 0xa2, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x8f, 0x00, 0x30,
+  0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xd1, 0xcf, 0x2d, 0x21, 0x38, 0xe4, 0x81, 0xa6,
+  0xf2, 0xe5, 0xca, 0xac, 0x09, 0x2b, 0x04, 0x2a, 0x52, 0x76, 0x2f, 0xa3, 0x4b, 0x43, 0xc2, 0xd6,
+  0xb5, 0x3e, 0x2b, 0x29, 0x6f, 0x1b, 0x7d, 0x36, 0x60, 0xcd, 0x71, 0xf4, 0xcf, 0x8a, 0x24, 0xac,
+  0x8f, 0x5f, 0x78, 0x70, 0xc9, 0x84, 0x48, 0xfb, 0x1d, 0xcb, 0xee, 0x34, 0x3c, 0x4c, 0xe1, 0x1a,
+  0x92, 0x54, 0x43, 0x45, 0xe0, 0xdd, 0x14, 0xd5, 0xac, 0x13, 0xae, 0xcc, 0x45, 0xdc, 0x52, 0xdd,
+  0x45, 0x22, 0x10, 0xab, 0xb2, 0x1b, 0x3e, 0xad, 0x36, 0x6f, 0x00, 0x59, 0xb6, 0xfd, 0x27, 0xb8,
+  0x57, 0xbb, 0x66, 0x72, 0x1e, 0x7b, 0xe8, 0xc7, 0xaf, 0x5e, 0x65, 0x5c, 0x58, 0x3d, 0x9e, 0x78,
+  0x26, 0xb7, 0x70, 0x9a, 0xe7, 0x3c, 0xfc, 0x90, 0x64, 0xb2, 0xb2, 0xb2, 0x80, 0x22, 0xb3, 0x1c,
+  0x23, 0x73, 0x6a, 0xe3, 0xcb, 0x5b, 0x4e, 0x29, 0x71, 0xdd, 0xfd, 0xd7, 0x15, 0x3a, 0xd6, 0xa3,
+  0xe0, 0x4a, 0x53, 0x65, 0xa6, 0xae, 0x6a, 0x83, 0xb0, 0x00, 0x3f, 0x64, 0x4b, 0x01, 0xcd, 0x97,
+  0xb1, 0xe1, 0x54, 0x1e, 0xa2, 0x33, 0x4e, 0xf0, 0x13, 0x33, 0x80, 0xe5, 0x41, 0x9c, 0x5e, 0xb3,
+  0x5d, 0xae, 0x53, 0x2c, 0x41, 0x51, 0xf2, 0x00, 0x3e, 0x03, 0xe2, 0x0d, 0xa4, 0xf5, 0x24, 0x08,
+  0x46, 0xc2, 0xed, 0x6b, 0xf2, 0xe0, 0x1b, 0x04, 0xb7, 0xe8, 0xda, 0x85, 0xa4, 0x2f, 0x4b, 0x53,
+  0xfa, 0x76, 0x72, 0x0a, 0x28, 0xbf, 0x3c, 0xa8, 0x85, 0x03, 0xee, 0x51, 0xb5, 0x5c, 0xa9, 0xa5,
+  0x70, 0x47, 0x07, 0x11, 0x32, 0xc5, 0x5f, 0x7a, 0x07, 0xfb, 0x5f, 0x4a, 0x52, 0x65, 0x33, 0x0c,
+  0x17, 0x8e, 0x74, 0xe5, 0xec, 0x7d, 0x52, 0xa0, 0xd4, 0xef, 0x64, 0xcc, 0x5e, 0xe2, 0x3d, 0x46,
+  0x1e, 0x73, 0xab, 0x43, 0x2d, 0x05, 0xfa, 0xa3, 0x6d, 0x86, 0x02, 0xe7, 0xc8, 0x5f, 0x44, 0xfe,
+  0xeb, 0x14, 0x73, 0x2d, 0xf4, 0x0b, 0x72, 0x49, 0xe3, 0xef, 0x55, 0x05, 0x1b, 0x2f, 0xf9, 0x73,
+  0xeb, 0xed, 0xcc, 0x5e, 0x52, 0x17, 0x43, 0x94, 0x85, 0xc7, 0x0e, 0x73, 0x89, 0x22, 0xdc, 0x02,
+  0x5f, 0x99, 0x69, 0x58, 0x16, 0x89, 0x1e, 0x6f, 0x75, 0xf8, 0xd3, 0xe7, 0x0a, 0xb1, 0x01, 0x42,
+  0x71, 0xa6, 0xc5, 0xb2, 0xd0, 0xc0, 0x75, 0x96, 0x2e, 0xc2, 0x32, 0x49, 0x0a, 0xe8, 0x85, 0xbd,
+  0x22, 0x4c, 0x95, 0xd4, 0xf8, 0x2d, 0x72, 0x05, 0x4f, 0x0e, 0x56, 0x9c, 0xc3, 0x30, 0x3d, 0xfd,
+  0x30, 0x63, 0x92, 0x72, 0x6b, 0xaf, 0x80, 0x9d, 0xd0, 0xc2, 0x36, 0xe7, 0xc1, 0x37, 0xd0, 0x64,
+  0x88, 0x64, 0x3c, 0x33, 0xdd, 0x87, 0xdd, 0xd9, 0xa2, 0x79, 0x44, 0xd8, 0x25, 0x84, 0x0e, 0xfd,
+  0x9d, 0xd6, 0xc1, 0x7a, 0x2d, 0x23, 0x08, 0x9d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x5e, 0x30,
+  0x5c, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
+  0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0xfe, 0x30, 0x1d, 0x06, 0x03,
+  0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x46, 0xcd, 0xb4, 0x52, 0x02, 0x29, 0x26, 0xc7, 0x52,
+  0x23, 0x81, 0x65, 0xcd, 0x87, 0x2f, 0x96, 0x1b, 0x01, 0x2c, 0xc5, 0x30, 0x20, 0x06, 0x03, 0x55,
+  0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+  0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x0d, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01,
+  0x00, 0x71, 0x14, 0xca, 0xfe, 0x03, 0x92, 0xc6, 0x88, 0x52, 0x76, 0x43, 0xd9, 0x8a, 0xf7, 0x22,
+  0x94, 0xef, 0x40, 0xa7, 0xc3, 0x7b, 0x6f, 0xb4, 0xd0, 0x42, 0xc3, 0x59, 0x1f, 0x77, 0xef, 0xac,
+  0x18, 0xce, 0x7c, 0xab, 0x48, 0x85, 0x22, 0xf1, 0x50, 0x2c, 0xe0, 0x63, 0x4d, 0x9d, 0x0e, 0xed,
+  0x38, 0xff, 0xd9, 0xed, 0x3c, 0x7e, 0x3e, 0x84, 0xb1, 0xa7, 0x78, 0x62, 0x37, 0x39, 0x6d, 0xd5,
+  0x5d, 0x46, 0x9a, 0x6f, 0x63, 0xc2, 0xa7, 0x90, 0xf9, 0x7a, 0xa7, 0x4b, 0xa2, 0x8a, 0xa8, 0x50,
+  0x13, 0x16, 0x9c, 0x4f, 0xcc, 0x28, 0x58, 0x6c, 0x9f, 0x65, 0x6e, 0xf0, 0x9a, 0x92, 0x59, 0x94,
+  0xa4, 0xb5, 0xfd, 0x8f, 0xf0, 0x7c, 0x1e, 0xba, 0xc3, 0x21, 0x13, 0xfb, 0x33, 0xba, 0xad, 0x4b,
+  0x1d, 0x42, 0x23, 0x16, 0x8b, 0x3e, 0xcd, 0xb5, 0x69, 0x9c, 0x7c, 0xa1, 0x9b, 0x92, 0xc1, 0x2f,
+  0x9c, 0x89, 0x3f, 0x28, 0x24, 0x67, 0x48, 0x47, 0xf0, 0xb1, 0xc0, 0xf0, 0x4c, 0xbf, 0xf6, 0x64,
+  0xde, 0x33, 0xc3, 0xd6, 0x5b, 0xe6, 0xc3, 0xdd, 0xa5, 0xba, 0x42, 0x02, 0x0f, 0xbc, 0xbe, 0xde,
+  0x14, 0x12, 0x7c, 0xfb, 0xe6, 0xbb, 0xdd, 0xf2, 0x6b, 0xd7, 0x75, 0xe6, 0xf5, 0xda, 0xbe, 0xe9,
+  0xbf, 0xa6, 0x87, 0x09, 0x41, 0x6c, 0x9d, 0x19, 0x9c, 0xb1, 0x7c, 0x89, 0x9f, 0x32, 0xb3, 0x0a,
+  0x59, 0x10, 0xc6, 0x8c, 0xa0, 0x5b, 0xda, 0xa6, 0xa3, 0xf8, 0x33, 0x77, 0x7a, 0xf4, 0xb0, 0x8a,
+  0xcf, 0xc8, 0x3f, 0x2e, 0xb8, 0xf1, 0x9e, 0x7b, 0x47, 0x2d, 0x85, 0x3b, 0x58, 0xcd, 0x4b, 0xbc,
+  0x87, 0xd2, 0xf3, 0xcd, 0x36, 0x80, 0x9b, 0x4a, 0x0f, 0x24, 0x30, 0x1d, 0x3f, 0x6f, 0x56, 0xcf,
+  0x6e, 0x2d, 0xcf, 0xa8, 0x17, 0xd5, 0x97, 0x0b, 0x22, 0xa6, 0x59, 0xef, 0xef, 0xd4, 0x9a, 0x0e,
+  0x6f, 0xb9, 0xf0, 0x48, 0x2a, 0x54, 0x22, 0x77, 0x27, 0x90, 0x84, 0x42, 0x56, 0x85, 0x80, 0x78,
+  0x4f, 0xd9, 0x14, 0x2a, 0xf0, 0x5d, 0x6b, 0x46, 0x60, 0x3d, 0xad, 0xa5, 0xa2, 0xb9, 0x04, 0x23,
+  0x92, 0x1b, 0x70, 0xa3, 0xdb, 0xaa, 0xf0, 0x5f, 0x1c, 0xd8, 0x26, 0xbb, 0x51, 0x17, 0xfc, 0x93,
+  0x6d, 0x70, 0x19, 0x54, 0xe2, 0x6f, 0x82, 0x8a, 0x49, 0xa6, 0x19, 0xcc, 0x97, 0x53, 0x90, 0x27,
+  0xd9, 0x8d, 0xaa, 0x8c, 0xc3, 0x2b, 0xbc, 0x0a, 0x72, 0x3a, 0x41, 0xb8, 0xfa, 0x1e, 0xbb, 0x8b,
+  0x27, 0x06, 0x75, 0x53, 0x91, 0xac, 0x8d, 0x75, 0xf2, 0xa6, 0xea, 0x85, 0x7e, 0x34, 0x06, 0x9e,
+  0xf9, 0xe9, 0x13, 0xa3, 0xfe, 0x2e, 0x38, 0x4b, 0x3f, 0x61, 0x11, 0x1f, 0x6b, 0xd3, 0xfe, 0xc9,
+  0x13, 0xbc, 0x12, 0xfe, 0xbc, 0xff, 0xaa, 0x38, 0x73, 0x8a, 0x73, 0x8c, 0xcf, 0xcc, 0xd3, 0xe7,
+  0xba, 0x98, 0xfd, 0xf4, 0xf5, 0xf6, 0xa9, 0xc8, 0x07, 0x5b, 0x16, 0xae, 0x76, 0x86, 0x24, 0x25,
+  0xcc, 0x7c, 0xdb, 0x1e, 0x7f, 0xc4, 0xe4, 0xd3, 0x89, 0x5a, 0x91, 0x6a, 0x9c, 0x93, 0x03, 0xd2,
+  0xd2, 0xc0, 0x29, 0x69, 0x58, 0x52, 0x6c, 0xca, 0x91, 0x7d, 0xd2, 0x3d, 0xc7, 0x2f, 0x8a, 0x4e,
+  0x55, 0x03, 0x34, 0x16, 0x01, 0x2f, 0x4f, 0x57, 0xea, 0x10, 0xa7, 0xfb, 0xe3, 0x2e, 0x2c, 0x7f,
+  0x5d, 0x27, 0x93, 0x74, 0x95, 0x25, 0x1a, 0x1e, 0x54, 0x1a, 0xb6, 0xe1, 0xdc, 0xc8, 0xe4, 0x84,
+  0xeb, 0x38, 0x0f, 0x05, 0x74, 0xf3, 0x3a, 0xf9, 0xd8, 0x00, 0x43, 0xe9, 0x24, 0x1e, 0x45, 0xb4,
+  0xe2, 0x38, 0x8b, 0x6a, 0x4f, 0xb6, 0x0b, 0x1d, 0xac, 0xbc, 0xec, 0xda, 0x41, 0x9c, 0x7f, 0xa8,
+  0x15, 0x09, 0x3b, 0x0b, 0x99, 0xc4, 0x48, 0xdd, 0xde, 0x0d, 0x65, 0x86, 0x72, 0xaa, 0x0a, 0x4e,
+  0x71, 0x30, 0x82, 0x03, 0xeb, 0x30, 0x82, 0x02, 0x53, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01,
+  0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
+  0x30, 0x2b, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x69, 0x6e, 0x74,
+  0x65, 0x6c, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x69, 0x6e, 0x74, 0x65,
+  0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x63, 0x65, 0x72, 0x74, 0x30, 0x1e, 0x17,
+  0x0d, 0x32, 0x32, 0x30, 0x31, 0x30, 0x35, 0x30, 0x36, 0x31, 0x31, 0x30, 0x36, 0x5a, 0x17, 0x0d,
+  0x33, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x36, 0x31, 0x31, 0x30, 0x36, 0x5a, 0x30, 0x28, 0x31,
+  0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1d, 0x69, 0x6e, 0x74, 0x65, 0x6c, 0x20,
+  0x74, 0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x72, 0x65, 0x71, 0x75, 0x73, 0x65, 0x74,
+  0x65, 0x72, 0x20, 0x63, 0x65, 0x72, 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
+  0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x93, 0x47, 0xf3, 0x71, 0x6b, 0x24, 0x1e, 0xc0,
+  0xeb, 0x6b, 0x22, 0x23, 0xe7, 0xc8, 0x10, 0x9d, 0xb2, 0xef, 0x1e, 0x65, 0xe9, 0xff, 0xd6, 0x37,
+  0xee, 0xc5, 0x3f, 0x29, 0x25, 0x94, 0xb4, 0x30, 0x97, 0x51, 0xe3, 0x51, 0xa4, 0x39, 0xd1, 0x27,
+  0x32, 0x9e, 0x6b, 0x80, 0xc2, 0x29, 0xf2, 0x28, 0xd1, 0x49, 0xdc, 0x62, 0x27, 0x5b, 0x3f, 0xce,
+  0x83, 0xd7, 0x7b, 0x09, 0x37, 0x48, 0x16, 0x7f, 0x2e, 0x6e, 0xfa, 0x67, 0xaa, 0x92, 0x17, 0xcb,
+  0xff, 0x4b, 0xe3, 0x1b, 0xd1, 0xa6, 0xe3, 0x6c, 0x4d, 0x9f, 0x9e, 0xc7, 0x01, 0xed, 0x9f, 0x14,
+  0xb0, 0x34, 0x44, 0xa2, 0x88, 0x28, 0xf2, 0x3f, 0xad, 0xf2, 0xf7, 0x51, 0x8c, 0xfe, 0x43, 0x73,
+  0xfa, 0x8d, 0x2f, 0x63, 0x8c, 0x0e, 0xe5, 0x27, 0xdc, 0x12, 0x81, 0x26, 0xea, 0x92, 0x67, 0x7d,
+  0xc9, 0xfc, 0xec, 0x4c, 0xcc, 0x79, 0x4d, 0x2d, 0xfe, 0xf6, 0x63, 0xb7, 0x63, 0xca, 0x70, 0x24,
+  0xe0, 0x23, 0x53, 0x92, 0xe8, 0x56, 0xb7, 0x85, 0x6d, 0x25, 0x9e, 0xe0, 0x24, 0xa8, 0x5c, 0xe0,
+  0x0f, 0xc1, 0xb6, 0x20, 0x2f, 0x85, 0x2a, 0x67, 0xf6, 0x1b, 0x58, 0x60, 0x5a, 0x14, 0xda, 0xc2,
+  0x03, 0x10, 0x79, 0x33, 0x3c, 0x41, 0xc6, 0xbe, 0xd2, 0xee, 0x2f, 0x65, 0xd5, 0xad, 0x9c, 0xc6,
+  0x09, 0xae, 0x26, 0xf2, 0xac, 0xc2, 0x65, 0x12, 0x74, 0x09, 0xe8, 0x89, 0x66, 0xf6, 0x95, 0xb8,
+  0x6a, 0x5f, 0x96, 0xc2, 0x3c, 0x9f, 0x01, 0x52, 0xa8, 0xc8, 0x4e, 0xd8, 0xba, 0x95, 0x38, 0x5b,
+  0xf8, 0xc6, 0x43, 0x54, 0xac, 0x63, 0x90, 0xd4, 0xde, 0x11, 0x40, 0x27, 0xe5, 0x12, 0x1d, 0x72,
+  0xa2, 0xec, 0xad, 0x0a, 0x8b, 0x68, 0x21, 0x9d, 0xea, 0x16, 0x70, 0x5f, 0x32, 0x3a, 0xed, 0x4f,
+  0x0b, 0xb2, 0x44, 0x1f, 0x44, 0x9b, 0x4c, 0x03, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0x9c,
+  0x30, 0x81, 0x99, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30,
+  0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xe0, 0x30, 0x1d,
+  0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x7c, 0x69, 0x5e, 0x84, 0xbb, 0xc7, 0x6b,
+  0xfc, 0x45, 0x70, 0xa4, 0x4b, 0x1e, 0x67, 0x70, 0x04, 0xa4, 0x37, 0xdd, 0x72, 0x30, 0x31, 0x06,
+  0x03, 0x55, 0x1d, 0x11, 0x04, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
+  0x01, 0x83, 0x1c, 0x82, 0x12, 0x01, 0xa0, 0x18, 0x0c, 0x16, 0x41, 0x43, 0x4d, 0x45, 0x3a, 0x57,
+  0x49, 0x44, 0x47, 0x45, 0x54, 0x3a, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
+  0x30, 0x2a, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x20, 0x30, 0x1e, 0x06, 0x08,
+  0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+  0x03, 0x02, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x09, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x81, 0x00,
+  0x8e, 0x19, 0x08, 0xec, 0x7a, 0xcc, 0x6d, 0x04, 0x5f, 0xb7, 0xf9, 0xd2, 0xcd, 0x76, 0xee, 0x44,
+  0x1b, 0x7c, 0x19, 0xcb, 0x18, 0xdd, 0x60, 0x50, 0x3a, 0x54, 0xb1, 0x75, 0x17, 0xf6, 0xce, 0x19,
+  0x15, 0x09, 0x9e, 0x5b, 0xfc, 0x5c, 0xb3, 0x20, 0x8d, 0xcb, 0x9d, 0xfc, 0x23, 0x12, 0x68, 0x87,
+  0x55, 0x0d, 0x3b, 0x5f, 0x9f, 0x4e, 0xb2, 0x17, 0x13, 0x0b, 0xc4, 0x6f, 0xbe, 0x43, 0x75, 0xa6,
+  0xb7, 0x3c, 0x0e, 0xe0, 0xdf, 0x84, 0xe5, 0x88, 0x46, 0x08, 0xc3, 0x36, 0x1b, 0x31, 0x02, 0x92,
+  0x7c, 0x53, 0xc4, 0x08, 0x63, 0x3e, 0x46, 0x75, 0xd7, 0x35, 0x9a, 0xd0, 0x76, 0x71, 0xf9, 0x57,
+  0x97, 0xc7, 0x3c, 0x3b, 0xce, 0x7a, 0x82, 0x95, 0x15, 0x8e, 0x20, 0xcc, 0x7b, 0xa0, 0xc4, 0x68,
+  0x21, 0x26, 0x9c, 0xfd, 0x29, 0x83, 0x41, 0x19, 0x98, 0xb6, 0x8a, 0x3a, 0x06, 0x5f, 0x01, 0x1b,
+  0x80, 0xac, 0x33, 0xd9, 0x0c, 0x9c, 0xea, 0x70, 0xd7, 0xf5, 0x1e, 0xb0, 0x78, 0x24, 0xbc, 0x59,
+  0xaf, 0x07, 0xc6, 0x16, 0x46, 0xdd, 0x9d, 0x00, 0x9a, 0xc8, 0x9a, 0x04, 0x19, 0x4d, 0x62, 0xa9,
+  0x4f, 0x7c, 0x05, 0x24, 0x93, 0xc6, 0x01, 0xc5, 0xb2, 0x89, 0xe8, 0x62, 0x47, 0xbe, 0xa3, 0xd1,
+  0x9c, 0x47, 0x31, 0x06, 0x16, 0x6b, 0x3b, 0xf8, 0xad, 0xb0, 0x4c, 0xfb, 0x2b, 0x6b, 0x8e, 0x88,
+  0x53, 0x70, 0x75, 0x40, 0x30, 0xaf, 0xfe, 0xc5, 0xf3, 0x0f, 0x86, 0x8f, 0x58, 0x56, 0x67, 0xbd,
+  0x15, 0x1f, 0x8a, 0x5c, 0xa3, 0x8a, 0x9a, 0x88, 0xe5, 0xf2, 0xd3, 0x7f, 0xac, 0x56, 0x34, 0x21,
+  0x24, 0xf7, 0xde, 0x9d, 0x97, 0x9b, 0xe6, 0x20, 0xd6, 0x3d, 0x48, 0x73, 0x29, 0x23, 0xf9, 0x0f,
+  0xab, 0x04, 0xe6, 0x1d, 0x70, 0xee, 0xcb, 0x5a, 0xe5, 0x8a, 0xf4, 0xbc, 0x4b, 0xad, 0x18, 0xec,
+  0x25, 0x8a, 0xb8, 0x91, 0xf9, 0x53, 0xf4, 0xe4, 0xce, 0xa7, 0x54, 0xf6, 0x83, 0x66, 0x07, 0xc5,
+  0x51, 0x48, 0x20, 0x54, 0x5b, 0x5d, 0xc1, 0x80, 0x04, 0x17, 0x89, 0x14, 0x5a, 0x06, 0x34, 0x86,
+  0xdb, 0x8b, 0xaf, 0x04, 0x24, 0xd9, 0xbd, 0xa8, 0x27, 0x09, 0x51, 0xfe, 0x6e, 0x47, 0x3c, 0x29,
+  0x0a, 0x64, 0x3e, 0x0f, 0x00, 0xf1, 0xd9, 0xdc, 0xe9, 0xd1, 0x3c, 0xcf, 0xa4, 0xa9, 0x4f, 0x54,
+  0x02, 0xcf, 0xa1, 0x40, 0x49, 0x61, 0x2a, 0x07, 0xa2, 0x44, 0x35, 0x20, 0x20, 0x56, 0x1c, 0x27,
+  0xa2, 0xff, 0x07, 0x3e, 0x8b, 0xfe, 0x60, 0x42, 0x75, 0x0c, 0xe3, 0x8f, 0xee, 0x33, 0x8d, 0xfc,
+  0x3b, 0x53, 0x36, 0x39, 0x10, 0x1a, 0xe3, 0xd2, 0x09, 0x7b, 0x00, 0xd0, 0xbd, 0x39, 0xf4, 0xcc,
+  0xe3, 0x42, 0xd4, 0xa5, 0x2d, 0x0b, 0x58, 0xdf, 0x24, 0x7f, 0x85, 0x0a, 0xf2, 0x17, 0x76, 0xdd,
+};
+
+//
+// dump of end_requester.key.der
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  mTestEndCert[] = {
+  0x30, 0x82, 0x03, 0xeb, 0x30, 0x82, 0x02, 0x53, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
+  0x2b, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x69, 0x6e, 0x74, 0x65,
+  0x6c, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72,
+  0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x63, 0x65, 0x72, 0x74, 0x30, 0x1e, 0x17, 0x0d,
+  0x32, 0x32, 0x30, 0x31, 0x30, 0x35, 0x30, 0x36, 0x31, 0x31, 0x30, 0x36, 0x5a, 0x17, 0x0d, 0x33,
+  0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x36, 0x31, 0x31, 0x30, 0x36, 0x5a, 0x30, 0x28, 0x31, 0x26,
+  0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1d, 0x69, 0x6e, 0x74, 0x65, 0x6c, 0x20, 0x74,
+  0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x72, 0x65, 0x71, 0x75, 0x73, 0x65, 0x74, 0x65,
+  0x72, 0x20, 0x63, 0x65, 0x72, 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82,
+  0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x93, 0x47, 0xf3, 0x71, 0x6b, 0x24, 0x1e, 0xc0, 0xeb,
+  0x6b, 0x22, 0x23, 0xe7, 0xc8, 0x10, 0x9d, 0xb2, 0xef, 0x1e, 0x65, 0xe9, 0xff, 0xd6, 0x37, 0xee,
+  0xc5, 0x3f, 0x29, 0x25, 0x94, 0xb4, 0x30, 0x97, 0x51, 0xe3, 0x51, 0xa4, 0x39, 0xd1, 0x27, 0x32,
+  0x9e, 0x6b, 0x80, 0xc2, 0x29, 0xf2, 0x28, 0xd1, 0x49, 0xdc, 0x62, 0x27, 0x5b, 0x3f, 0xce, 0x83,
+  0xd7, 0x7b, 0x09, 0x37, 0x48, 0x16, 0x7f, 0x2e, 0x6e, 0xfa, 0x67, 0xaa, 0x92, 0x17, 0xcb, 0xff,
+  0x4b, 0xe3, 0x1b, 0xd1, 0xa6, 0xe3, 0x6c, 0x4d, 0x9f, 0x9e, 0xc7, 0x01, 0xed, 0x9f, 0x14, 0xb0,
+  0x34, 0x44, 0xa2, 0x88, 0x28, 0xf2, 0x3f, 0xad, 0xf2, 0xf7, 0x51, 0x8c, 0xfe, 0x43, 0x73, 0xfa,
+  0x8d, 0x2f, 0x63, 0x8c, 0x0e, 0xe5, 0x27, 0xdc, 0x12, 0x81, 0x26, 0xea, 0x92, 0x67, 0x7d, 0xc9,
+  0xfc, 0xec, 0x4c, 0xcc, 0x79, 0x4d, 0x2d, 0xfe, 0xf6, 0x63, 0xb7, 0x63, 0xca, 0x70, 0x24, 0xe0,
+  0x23, 0x53, 0x92, 0xe8, 0x56, 0xb7, 0x85, 0x6d, 0x25, 0x9e, 0xe0, 0x24, 0xa8, 0x5c, 0xe0, 0x0f,
+  0xc1, 0xb6, 0x20, 0x2f, 0x85, 0x2a, 0x67, 0xf6, 0x1b, 0x58, 0x60, 0x5a, 0x14, 0xda, 0xc2, 0x03,
+  0x10, 0x79, 0x33, 0x3c, 0x41, 0xc6, 0xbe, 0xd2, 0xee, 0x2f, 0x65, 0xd5, 0xad, 0x9c, 0xc6, 0x09,
+  0xae, 0x26, 0xf2, 0xac, 0xc2, 0x65, 0x12, 0x74, 0x09, 0xe8, 0x89, 0x66, 0xf6, 0x95, 0xb8, 0x6a,
+  0x5f, 0x96, 0xc2, 0x3c, 0x9f, 0x01, 0x52, 0xa8, 0xc8, 0x4e, 0xd8, 0xba, 0x95, 0x38, 0x5b, 0xf8,
+  0xc6, 0x43, 0x54, 0xac, 0x63, 0x90, 0xd4, 0xde, 0x11, 0x40, 0x27, 0xe5, 0x12, 0x1d, 0x72, 0xa2,
+  0xec, 0xad, 0x0a, 0x8b, 0x68, 0x21, 0x9d, 0xea, 0x16, 0x70, 0x5f, 0x32, 0x3a, 0xed, 0x4f, 0x0b,
+  0xb2, 0x44, 0x1f, 0x44, 0x9b, 0x4c, 0x03, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0x9c, 0x30,
+  0x81, 0x99, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00,
+  0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xe0, 0x30, 0x1d, 0x06,
+  0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x7c, 0x69, 0x5e, 0x84, 0xbb, 0xc7, 0x6b, 0xfc,
+  0x45, 0x70, 0xa4, 0x4b, 0x1e, 0x67, 0x70, 0x04, 0xa4, 0x37, 0xdd, 0x72, 0x30, 0x31, 0x06, 0x03,
+  0x55, 0x1d, 0x11, 0x04, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01,
+  0x83, 0x1c, 0x82, 0x12, 0x01, 0xa0, 0x18, 0x0c, 0x16, 0x41, 0x43, 0x4d, 0x45, 0x3a, 0x57, 0x49,
+  0x44, 0x47, 0x45, 0x54, 0x3a, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x30,
+  0x2a, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b,
+  0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
+  0x02, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x09, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x81, 0x00, 0x8e,
+  0x19, 0x08, 0xec, 0x7a, 0xcc, 0x6d, 0x04, 0x5f, 0xb7, 0xf9, 0xd2, 0xcd, 0x76, 0xee, 0x44, 0x1b,
+  0x7c, 0x19, 0xcb, 0x18, 0xdd, 0x60, 0x50, 0x3a, 0x54, 0xb1, 0x75, 0x17, 0xf6, 0xce, 0x19, 0x15,
+  0x09, 0x9e, 0x5b, 0xfc, 0x5c, 0xb3, 0x20, 0x8d, 0xcb, 0x9d, 0xfc, 0x23, 0x12, 0x68, 0x87, 0x55,
+  0x0d, 0x3b, 0x5f, 0x9f, 0x4e, 0xb2, 0x17, 0x13, 0x0b, 0xc4, 0x6f, 0xbe, 0x43, 0x75, 0xa6, 0xb7,
+  0x3c, 0x0e, 0xe0, 0xdf, 0x84, 0xe5, 0x88, 0x46, 0x08, 0xc3, 0x36, 0x1b, 0x31, 0x02, 0x92, 0x7c,
+  0x53, 0xc4, 0x08, 0x63, 0x3e, 0x46, 0x75, 0xd7, 0x35, 0x9a, 0xd0, 0x76, 0x71, 0xf9, 0x57, 0x97,
+  0xc7, 0x3c, 0x3b, 0xce, 0x7a, 0x82, 0x95, 0x15, 0x8e, 0x20, 0xcc, 0x7b, 0xa0, 0xc4, 0x68, 0x21,
+  0x26, 0x9c, 0xfd, 0x29, 0x83, 0x41, 0x19, 0x98, 0xb6, 0x8a, 0x3a, 0x06, 0x5f, 0x01, 0x1b, 0x80,
+  0xac, 0x33, 0xd9, 0x0c, 0x9c, 0xea, 0x70, 0xd7, 0xf5, 0x1e, 0xb0, 0x78, 0x24, 0xbc, 0x59, 0xaf,
+  0x07, 0xc6, 0x16, 0x46, 0xdd, 0x9d, 0x00, 0x9a, 0xc8, 0x9a, 0x04, 0x19, 0x4d, 0x62, 0xa9, 0x4f,
+  0x7c, 0x05, 0x24, 0x93, 0xc6, 0x01, 0xc5, 0xb2, 0x89, 0xe8, 0x62, 0x47, 0xbe, 0xa3, 0xd1, 0x9c,
+  0x47, 0x31, 0x06, 0x16, 0x6b, 0x3b, 0xf8, 0xad, 0xb0, 0x4c, 0xfb, 0x2b, 0x6b, 0x8e, 0x88, 0x53,
+  0x70, 0x75, 0x40, 0x30, 0xaf, 0xfe, 0xc5, 0xf3, 0x0f, 0x86, 0x8f, 0x58, 0x56, 0x67, 0xbd, 0x15,
+  0x1f, 0x8a, 0x5c, 0xa3, 0x8a, 0x9a, 0x88, 0xe5, 0xf2, 0xd3, 0x7f, 0xac, 0x56, 0x34, 0x21, 0x24,
+  0xf7, 0xde, 0x9d, 0x97, 0x9b, 0xe6, 0x20, 0xd6, 0x3d, 0x48, 0x73, 0x29, 0x23, 0xf9, 0x0f, 0xab,
+  0x04, 0xe6, 0x1d, 0x70, 0xee, 0xcb, 0x5a, 0xe5, 0x8a, 0xf4, 0xbc, 0x4b, 0xad, 0x18, 0xec, 0x25,
+  0x8a, 0xb8, 0x91, 0xf9, 0x53, 0xf4, 0xe4, 0xce, 0xa7, 0x54, 0xf6, 0x83, 0x66, 0x07, 0xc5, 0x51,
+  0x48, 0x20, 0x54, 0x5b, 0x5d, 0xc1, 0x80, 0x04, 0x17, 0x89, 0x14, 0x5a, 0x06, 0x34, 0x86, 0xdb,
+  0x8b, 0xaf, 0x04, 0x24, 0xd9, 0xbd, 0xa8, 0x27, 0x09, 0x51, 0xfe, 0x6e, 0x47, 0x3c, 0x29, 0x0a,
+  0x64, 0x3e, 0x0f, 0x00, 0xf1, 0xd9, 0xdc, 0xe9, 0xd1, 0x3c, 0xcf, 0xa4, 0xa9, 0x4f, 0x54, 0x02,
+  0xcf, 0xa1, 0x40, 0x49, 0x61, 0x2a, 0x07, 0xa2, 0x44, 0x35, 0x20, 0x20, 0x56, 0x1c, 0x27, 0xa2,
+  0xff, 0x07, 0x3e, 0x8b, 0xfe, 0x60, 0x42, 0x75, 0x0c, 0xe3, 0x8f, 0xee, 0x33, 0x8d, 0xfc, 0x3b,
+  0x53, 0x36, 0x39, 0x10, 0x1a, 0xe3, 0xd2, 0x09, 0x7b, 0x00, 0xd0, 0xbd, 0x39, 0xf4, 0xcc, 0xe3,
+  0x42, 0xd4, 0xa5, 0x2d, 0x0b, 0x58, 0xdf, 0x24, 0x7f, 0x85, 0x0a, 0xf2, 0x17, 0x76, 0xdd,
+};
+
+UNIT_TEST_STATUS
+EFIAPI
+TestVerifyX509 (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  BOOLEAN      Status;
+  CONST UINT8  *LeafCert;
+  UINTN        LeafCertLen;
+  UINTN        CertVersion;
+  UINT8        Asn1Buffer[1024];
+  UINTN        Asn1BufferLen;
+  UINTN        SubjectSize;
+  UINT8        *Subject;
+  UINT8        EndEertFrom[64];
+  UINTN        EndEertFromLen;
+  UINT8        EndEertTo[64];
+  UINTN        EndEertToLen;
+  UINT8        DateTime1[64];
+  UINT8        DateTime2[64];
+
+  //
+  // X509 Certificate Verification.
+  //
+  Status = X509VerifyCert (mTestCert, sizeof (mTestCert), mTestCaCert, sizeof (mTestCaCert));
+  UT_ASSERT_TRUE (Status);
+
+  //
+  // X509 Certificate Chain Verification.
+  //
+  Status = X509VerifyCertChain (mTestCaCert, sizeof (mTestCaCert), mTestBundleCert, sizeof (mTestBundleCert));
+  UT_ASSERT_TRUE (Status);
+
+  //
+  // X509 Get leaf certificate from cert_chain Verificate.
+  //
+  Status = X509GetCertFromCertChain (mTestBundleCert, sizeof (mTestBundleCert), -1, &LeafCert, &LeafCertLen);
+  UT_ASSERT_TRUE (Status);
+
+  UT_ASSERT_EQUAL (LeafCertLen, sizeof (mTestEndCert));
+  UT_ASSERT_MEM_EQUAL (LeafCert, mTestEndCert, LeafCertLen);
+
+  //
+  // X509 Get leaf certificate from cert_chain Verificate.
+  //
+  Status = X509GetCertFromCertChain (mTestBundleCert, sizeof (mTestBundleCert), 2, &LeafCert, &LeafCertLen);
+  UT_ASSERT_TRUE (Status);
+
+  UT_ASSERT_EQUAL (LeafCertLen, sizeof (mTestEndCert));
+  UT_ASSERT_MEM_EQUAL (LeafCert, mTestEndCert, LeafCertLen);
+
+  //
+  // X509 Get root certificate from cert_chain Verificate.
+  //
+  Status = X509GetCertFromCertChain (mTestBundleCert, sizeof (mTestBundleCert), 0, &LeafCert, &LeafCertLen);
+  UT_ASSERT_TRUE (Status);
+
+  UT_ASSERT_EQUAL (LeafCertLen, sizeof (mTestCaCert));
+  UT_ASSERT_MEM_EQUAL (LeafCert, mTestCaCert, LeafCertLen);
+
+  //
+  // Get version from X509 Certificate.
+  //
+  CertVersion = 0;
+  Status      = X509GetVersion (mTestCert, sizeof (mTestCert), &CertVersion);
+  UT_ASSERT_TRUE (Status);
+
+  //
+  // Get Serial from X509 Certificate.
+  //
+  Asn1BufferLen = 1024;
+  ZeroMem (Asn1Buffer, Asn1BufferLen);
+  Status = X509GetSerialNumber (mTestCert, sizeof (mTestCert), Asn1Buffer, &Asn1BufferLen);
+  UT_ASSERT_TRUE (Status);
+
+  //
+  // X509 Certificate subject Retrieving.
+  //
+  SubjectSize = 0;
+  Status      = X509GetIssuerName (mTestCert, sizeof (mTestCert), NULL, &SubjectSize);
+  UT_ASSERT_TRUE (!Status);
+  Subject = AllocatePool (SubjectSize);
+  Status  = X509GetIssuerName (mTestCert, sizeof (mTestCert), Subject, &SubjectSize);
+  UT_ASSERT_TRUE (Status);
+  FreePool (Subject);
+
+  //
+  // Get X509GetSubjectAltName.
+  //
+  Asn1BufferLen = 1024;
+  ZeroMem (Asn1Buffer, Asn1BufferLen);
+  Status = X509GetExtensionData (mTestEndCert, sizeof (mTestEndCert), mOidSubjectAltName, sizeof (mOidSubjectAltName), Asn1Buffer, &Asn1BufferLen);
+  UT_ASSERT_TRUE (Status);
+
+  //
+  // Get X509 Validity.
+  //
+  EndEertFromLen = 64;
+  EndEertToLen   = 64;
+  Status         = X509GetValidity (
+                     mTestEndCert,
+                     sizeof (mTestEndCert),
+                     EndEertFrom,
+                     &EndEertFromLen,
+                     EndEertTo,
+                     &EndEertToLen
+                     );
+  UT_ASSERT_TRUE (Status);
+
+  Asn1BufferLen = 64;
+  Status        = X509SetDateTime (
+                    "19700101000000Z",
+                    DateTime1,
+                    &Asn1BufferLen
+                    );
+  UT_ASSERT_TRUE (Status && (Asn1BufferLen != 0));
+
+  Asn1BufferLen = 64;
+  Status        = X509SetDateTime (
+                    "19700201000000Z",
+                    DateTime2,
+                    &Asn1BufferLen
+                    );
+  UT_ASSERT_TRUE (Status && (Asn1BufferLen != 0));
+
+  UT_ASSERT_TRUE (X509CompareDateTime (DateTime1, DateTime2) < 0);
+
+  return UNIT_TEST_PASSED;
+}
+
+TEST_DESC  mX509Test[] = {
+  //
+  // -----Description--------------------------------------Class----------------------Function---------------------------------Pre---------------------Post---------Context
+  //
+  { "TestVerifyX509()", "CryptoPkg.BaseCryptLib.Hkdf", TestVerifyX509, NULL, NULL, NULL },
+};
+
+UINTN  mX509TestNum = ARRAY_SIZE (mX509Test);
-- 
2.26.2.windows.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/4] CryptoPkg: add new X509 function definition.
  2022-09-25  8:54 ` [PATCH 1/4] CryptoPkg: add new X509 function definition Qi Zhang
@ 2022-10-10  0:34   ` Yao, Jiewen
  2022-10-10  4:30     ` Qi Zhang
  0 siblings, 1 reply; 7+ messages in thread
From: Yao, Jiewen @ 2022-10-10  0:34 UTC (permalink / raw)
  To: Zhang, Qi1, devel@edk2.groups.io; +Cc: Wang, Jian J, Lu, Xiaoyu1, Jiang, Guomin

Hi
I feel the function name X509SetDateTime() is very confusing. From the function comment, it means: "Format a DateTime object into DataTime Buffer".

I also find the comment in X509GetValidity(), "x509SetDateTime to get a DateTime object from a DateTimeStr"

It seems "DataTimeStr" is " DateTime string like YYYYMMDDhhmmssZ "
So what is the relationship among "DateTime object", "DateTime Buffer", and "DateTime Str" ?




> -----Original Message-----
> From: Zhang, Qi1 <qi1.zhang@intel.com>
> Sent: Sunday, September 25, 2022 4:54 PM
> To: devel@edk2.groups.io
> Cc: Zhang, Qi1 <qi1.zhang@intel.com>; Yao, Jiewen
> <jiewen.yao@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Lu, Xiaoyu1
> <xiaoyu1.lu@intel.com>; Jiang, Guomin <guomin.jiang@intel.com>
> Subject: [PATCH 1/4] CryptoPkg: add new X509 function definition.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4082
> 
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
> Cc: Guomin Jiang <guomin.jiang@intel.com>
> Signed-off-by: Qi Zhang <qi1.zhang@intel.com>
> ---
>  CryptoPkg/Include/Library/BaseCryptLib.h | 374
> +++++++++++++++++++++++
>  1 file changed, 374 insertions(+)
> 
> diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h
> b/CryptoPkg/Include/Library/BaseCryptLib.h
> index 3026299e29..d7bf29c93f 100644
> --- a/CryptoPkg/Include/Library/BaseCryptLib.h
> +++ b/CryptoPkg/Include/Library/BaseCryptLib.h
> @@ -2459,6 +2459,380 @@ ImageTimestampVerify (
>    OUT EFI_TIME     *SigningTime
> 
>    );
> 
> 
> 
> +/**
> 
> +  Retrieve the version from one X.509 certificate.
> 
> +
> 
> +  If Cert is NULL, then return FALSE.
> 
> +  If CertSize is 0, then return FALSE.
> 
> +  If this interface is not supported, then return FALSE.
> 
> +
> 
> +  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
> 
> +  @param[in]      CertSize     Size of the X509 certificate in bytes.
> 
> +  @param[out]     Version      Pointer to the retrieved version integer.
> 
> +
> 
> +  @retval TRUE           The certificate version retrieved successfully.
> 
> +  @retval FALSE          If  Cert is NULL or CertSize is Zero.
> 
> +  @retval FALSE          The operation is not supported.
> 
> +
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetVersion (
> 
> +  IN      CONST UINT8  *Cert,
> 
> +  IN      UINTN        CertSize,
> 
> +  OUT     UINTN        *Version
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Retrieve the serialNumber from one X.509 certificate.
> 
> +
> 
> +  If Cert is NULL, then return FALSE.
> 
> +  If CertSize is 0, then return FALSE.
> 
> +  If this interface is not supported, then return FALSE.
> 
> +
> 
> +  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
> 
> +  @param[in]      CertSize     Size of the X509 certificate in bytes.
> 
> +  @param[out]     SerialNumber  Pointer to the retrieved certificate
> SerialNumber bytes.
> 
> +  @param[in, out] SerialNumberSize  The size in bytes of the SerialNumber
> buffer on input,
> 
> +                               and the size of buffer returned SerialNumber on output.
> 
> +
> 
> +  @retval TRUE                     The certificate serialNumber retrieved
> successfully.
> 
> +  @retval FALSE                    If Cert is NULL or CertSize is Zero.
> 
> +                                   If SerialNumberSize is NULL.
> 
> +                                   If Certificate is invalid.
> 
> +  @retval FALSE                    If no SerialNumber exists.
> 
> +  @retval FALSE                    If the SerialNumber is NULL. The required buffer
> size
> 
> +                                   (including the final null) is returned in the
> 
> +                                   SerialNumberSize parameter.
> 
> +  @retval FALSE                    The operation is not supported.
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetSerialNumber (
> 
> +  IN      CONST UINT8 *Cert,
> 
> +  IN      UINTN CertSize,
> 
> +  OUT     UINT8 *SerialNumber, OPTIONAL
> 
> +  IN OUT  UINTN         *SerialNumberSize
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Retrieve the issuer bytes from one X.509 certificate.
> 
> +
> 
> +  If Cert is NULL, then return FALSE.
> 
> +  If CertIssuerSize is NULL, then return FALSE.
> 
> +  If this interface is not supported, then return FALSE.
> 
> +
> 
> +  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
> 
> +  @param[in]      CertSize     Size of the X509 certificate in bytes.
> 
> +  @param[out]     CertIssuer  Pointer to the retrieved certificate subject
> bytes.
> 
> +  @param[in, out] CertIssuerSize  The size in bytes of the CertIssuer buffer
> on input,
> 
> +                               and the size of buffer returned CertSubject on output.
> 
> +
> 
> +  @retval  TRUE   The certificate issuer retrieved successfully.
> 
> +  @retval  FALSE  Invalid certificate, or the CertIssuerSize is too small for
> the result.
> 
> +                  The CertIssuerSize will be updated with the required size.
> 
> +  @retval  FALSE  This interface is not supported.
> 
> +
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetIssuerName (
> 
> +  IN      CONST UINT8  *Cert,
> 
> +  IN      UINTN        CertSize,
> 
> +  OUT     UINT8        *CertIssuer,
> 
> +  IN OUT  UINTN        *CertIssuerSize
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Retrieve the Signature Algorithm from one X.509 certificate.
> 
> +
> 
> +  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
> 
> +  @param[in]      CertSize         Size of the X509 certificate in bytes.
> 
> +  @param[out]     Oid              Signature Algorithm Object identifier buffer.
> 
> +  @param[in,out]  OidSize          Signature Algorithm Object identifier buffer
> size
> 
> +
> 
> +  @retval TRUE           The certificate Extension data retrieved successfully.
> 
> +  @retval FALSE                    If Cert is NULL.
> 
> +                                   If OidSize is NULL.
> 
> +                                   If Oid is not NULL and *OidSize is 0.
> 
> +                                   If Certificate is invalid.
> 
> +  @retval FALSE                    If no SignatureType.
> 
> +  @retval FALSE                    If the Oid is NULL. The required buffer size
> 
> +                                   is returned in the OidSize.
> 
> +  @retval FALSE                    The operation is not supported.
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetSignatureAlgorithm (
> 
> +  IN CONST UINT8 *Cert,
> 
> +  IN       UINTN CertSize,
> 
> +  OUT   UINT8 *Oid, OPTIONAL
> 
> +  IN OUT   UINTN       *OidSize
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Retrieve Extension data from one X.509 certificate.
> 
> +
> 
> +  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
> 
> +  @param[in]      CertSize         Size of the X509 certificate in bytes.
> 
> +  @param[in]      Oid              Object identifier buffer
> 
> +  @param[in]      OidSize          Object identifier buffer size
> 
> +  @param[out]     ExtensionData    Extension bytes.
> 
> +  @param[in, out] ExtensionDataSize Extension bytes size.
> 
> +
> 
> +  @retval TRUE                     The certificate Extension data retrieved
> successfully.
> 
> +  @retval FALSE                    If Cert is NULL.
> 
> +                                   If ExtensionDataSize is NULL.
> 
> +                                   If ExtensionData is not NULL and *ExtensionDataSize is
> 0.
> 
> +                                   If Certificate is invalid.
> 
> +  @retval FALSE                    If no Extension entry match Oid.
> 
> +  @retval FALSE                    If the ExtensionData is NULL. The required
> buffer size
> 
> +                                   is returned in the ExtensionDataSize parameter.
> 
> +  @retval FALSE                    The operation is not supported.
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetExtensionData (
> 
> +  IN     CONST UINT8  *Cert,
> 
> +  IN     UINTN        CertSize,
> 
> +  IN     CONST UINT8  *Oid,
> 
> +  IN     UINTN        OidSize,
> 
> +  OUT UINT8           *ExtensionData,
> 
> +  IN OUT UINTN        *ExtensionDataSize
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Retrieve the Validity from one X.509 certificate
> 
> +
> 
> +  If Cert is NULL, then return FALSE.
> 
> +  If CertIssuerSize is NULL, then return FALSE.
> 
> +  If this interface is not supported, then return FALSE.
> 
> +
> 
> +  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
> 
> +  @param[in]      CertSize     Size of the X509 certificate in bytes.
> 
> +  @param[in]      From         notBefore Pointer to DateTime object.
> 
> +  @param[in,out]  FromSize     notBefore DateTime object size.
> 
> +  @param[in]      To           notAfter Pointer to DateTime object.
> 
> +  @param[in,out]  ToSize       notAfter DateTime object size.
> 
> +
> 
> +  Note: X509CompareDateTime to compare DateTime oject
> 
> +        x509SetDateTime to get a DateTime object from a DateTimeStr
> 
> +
> 
> +  @retval  TRUE   The certificate Validity retrieved successfully.
> 
> +  @retval  FALSE  Invalid certificate, or Validity retrieve failed.
> 
> +  @retval  FALSE  This interface is not supported.
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetValidity (
> 
> +  IN     CONST UINT8  *Cert,
> 
> +  IN     UINTN        CertSize,
> 
> +  IN     UINT8        *From,
> 
> +  IN OUT UINTN        *FromSize,
> 
> +  IN     UINT8        *To,
> 
> +  IN OUT UINTN        *ToSize
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Format a DateTime object into DataTime Buffer
> 
> +
> 
> +  If DateTimeStr is NULL, then return FALSE.
> 
> +  If DateTimeSize is NULL, then return FALSE.
> 
> +  If this interface is not supported, then return FALSE.
> 
> +
> 
> +  @param[in]      DateTimeStr      DateTime string like YYYYMMDDhhmmssZ
> 
> +                                   Ref: https://www.w3.org/TR/NOTE-datetime
> 
> +                                   Z stand for UTC time
> 
> +  @param[out]     DateTime         Pointer to a DateTime object.
> 
> +  @param[in,out]  DateTimeSize     DateTime object buffer size.
> 
> +
> 
> +  @retval TRUE                     The DateTime object create successfully.
> 
> +  @retval FALSE                    If DateTimeStr is NULL.
> 
> +                                   If DateTimeSize is NULL.
> 
> +                                   If DateTime is not NULL and *DateTimeSize is 0.
> 
> +                                   If Year Month Day Hour Minute Second combination is
> invalid datetime.
> 
> +  @retval FALSE                    If the DateTime is NULL. The required buffer
> size
> 
> +                                   (including the final null) is returned in the
> 
> +                                   DateTimeSize parameter.
> 
> +  @retval FALSE                    The operation is not supported.
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509SetDateTime (
> 
> +  IN   CHAR8    *DateTimeStr,
> 
> +  OUT  VOID     *DateTime,
> 
> +  IN OUT UINTN  *DateTimeSize
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Compare DateTime1 object and DateTime2 object.
> 
> +
> 
> +  If DateTime1 is NULL, then return -2.
> 
> +  If DateTime2 is NULL, then return -2.
> 
> +  If DateTime1 == DateTime2, then return 0
> 
> +  If DateTime1 > DateTime2, then return 1
> 
> +  If DateTime1 < DateTime2, then return -1
> 
> +
> 
> +  @param[in]      DateTime1         Pointer to a DateTime Ojbect
> 
> +  @param[in]      DateTime2         Pointer to a DateTime Object
> 
> +
> 
> +  @retval  0      If DateTime1 == DateTime2
> 
> +  @retval  1      If DateTime1 > DateTime2
> 
> +  @retval  -1     If DateTime1 < DateTime2
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +X509CompareDateTime (
> 
> +  IN  CONST  VOID  *DateTime1,
> 
> +  IN  CONST  VOID  *DateTime2
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Retrieve the Key Usage from one X.509 certificate.
> 
> +
> 
> +  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
> 
> +  @param[in]      CertSize         Size of the X509 certificate in bytes.
> 
> +  @param[out]     Usage            Key Usage (CRYPTO_X509_KU_*)
> 
> +
> 
> +  @retval  TRUE   The certificate Key Usage retrieved successfully.
> 
> +  @retval  FALSE  Invalid certificate, or Usage is NULL
> 
> +  @retval  FALSE  This interface is not supported.
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetKeyUsage (
> 
> +  IN    CONST UINT8  *Cert,
> 
> +  IN    UINTN        CertSize,
> 
> +  OUT   UINTN        *Usage
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Retrieve the Extended Key Usage from one X.509 certificate.
> 
> +
> 
> +  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
> 
> +  @param[in]      CertSize         Size of the X509 certificate in bytes.
> 
> +  @param[out]     Usage            Key Usage bytes.
> 
> +  @param[in, out] UsageSize        Key Usage buffer sizs in bytes.
> 
> +
> 
> +  @retval TRUE                     The Usage bytes retrieve successfully.
> 
> +  @retval FALSE                    If Cert is NULL.
> 
> +                                   If CertSize is NULL.
> 
> +                                   If Usage is not NULL and *UsageSize is 0.
> 
> +                                   If Cert is invalid.
> 
> +  @retval FALSE                    If the Usage is NULL. The required buffer size
> 
> +                                   is returned in the UsageSize parameter.
> 
> +  @retval FALSE                    The operation is not supported.
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetExtendedKeyUsage (
> 
> +  IN     CONST UINT8  *Cert,
> 
> +  IN     UINTN        CertSize,
> 
> +  OUT UINT8           *Usage,
> 
> +  IN OUT UINTN        *UsageSize
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Verify one X509 certificate was issued by the trusted CA.
> 
> +  @param[in]      RootCert          Trusted Root Certificate buffer
> 
> +
> 
> +  @param[in]      RootCertLength    Trusted Root Certificate buffer length
> 
> +  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509
> certificates
> 
> +                                    where the first certificate is signed by the Root
> 
> +                                    Certificate or is the Root Cerificate itself. and
> 
> +                                    subsequent cerificate is signed by the preceding
> 
> +                                    cerificate.
> 
> +  @param[in]      CertChainLength   Total length of the certificate chain, in
> bytes.
> 
> +
> 
> +  @retval  TRUE   All cerificates was issued by the first certificate in
> X509Certchain.
> 
> +  @retval  FALSE  Invalid certificate or the certificate was not issued by the
> given
> 
> +                  trusted CA.
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509VerifyCertChain (
> 
> +  IN CONST UINT8  *RootCert,
> 
> +  IN UINTN        RootCertLength,
> 
> +  IN CONST UINT8  *CertChain,
> 
> +  IN UINTN        CertChainLength
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Get one X509 certificate from CertChain.
> 
> +
> 
> +  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509
> certificates
> 
> +                                    where the first certificate is signed by the Root
> 
> +                                    Certificate or is the Root Cerificate itself. and
> 
> +                                    subsequent cerificate is signed by the preceding
> 
> +                                    cerificate.
> 
> +  @param[in]      CertChainLength   Total length of the certificate chain, in
> bytes.
> 
> +
> 
> +  @param[in]      CertIndex         Index of certificate. If index is -1 indecate
> the
> 
> +                                    last certificate in CertChain.
> 
> +
> 
> +  @param[out]     Cert              The certificate at the index of CertChain.
> 
> +  @param[out]     CertLength        The length certificate at the index of
> CertChain.
> 
> +
> 
> +  @retval  TRUE   Success.
> 
> +  @retval  FALSE  Failed to get certificate from certificate chain.
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetCertFromCertChain (
> 
> +  IN CONST UINT8   *CertChain,
> 
> +  IN UINTN         CertChainLength,
> 
> +  IN CONST INT32   CertIndex,
> 
> +  OUT CONST UINT8  **Cert,
> 
> +  OUT UINTN        *CertLength
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Retrieve the tag and length of the tag.
> 
> +
> 
> +  @param Ptr      The position in the ASN.1 data
> 
> +  @param End      End of data
> 
> +  @param Length   The variable that will receive the length
> 
> +  @param Tag      The expected tag
> 
> +
> 
> +  @retval      TRUE   Get tag successful
> 
> +  @retval      FALSe  Failed to get tag or tag not match
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +Asn1GetTag (
> 
> +  IN OUT UINT8   **Ptr,
> 
> +  IN     UINT8   *End,
> 
> +  OUT UINTN      *Length,
> 
> +  IN     UINT32  Tag
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Retrieve the basic constraints from one X.509 certificate.
> 
> +
> 
> +  @param[in]      Cert                     Pointer to the DER-encoded X509
> certificate.
> 
> +  @param[in]      CertSize                 size of the X509 certificate in bytes.
> 
> +  @param[out]     BasicConstraints         basic constraints bytes.
> 
> +  @param[in, out] BasicConstraintsSize     basic constraints buffer sizs in
> bytes.
> 
> +
> 
> +  @retval TRUE                     The basic constraints retrieve successfully.
> 
> +  @retval FALSE                    If cert is NULL.
> 
> +                                   If cert_size is NULL.
> 
> +                                   If basic_constraints is not NULL and
> *basic_constraints_size is 0.
> 
> +                                   If cert is invalid.
> 
> +  @retval FALSE                    The required buffer size is small.
> 
> +                                   The return buffer size is basic_constraints_size
> parameter.
> 
> +  @retval FALSE                    If no Extension entry match oid.
> 
> +  @retval FALSE                    The operation is not supported.
> 
> + **/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetExtendedBasicConstraints             (
> 
> +  CONST UINT8  *Cert,
> 
> +  UINTN        CertSize,
> 
> +  UINT8        *BasicConstraints,
> 
> +  UINTN        *BasicConstraintsSize
> 
> +  );
> 
> +
> 
>  //
> ==========================================================
> ===========================
> 
>  //    DH Key Exchange Primitive
> 
>  //
> ==========================================================
> ===========================
> 
> --
> 2.26.2.windows.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/4] CryptoPkg: add new X509 function definition.
  2022-10-10  0:34   ` Yao, Jiewen
@ 2022-10-10  4:30     ` Qi Zhang
  0 siblings, 0 replies; 7+ messages in thread
From: Qi Zhang @ 2022-10-10  4:30 UTC (permalink / raw)
  To: Yao, Jiewen, devel@edk2.groups.io
  Cc: Wang, Jian J, Lu, Xiaoyu1, Jiang, Guomin

Sorry for confusing. This function is to format DataTimeStr to a DataTime object through DataTime buffer.

So will change the function name to X509FormatDateTime() and modify this comment to "Format DataTimeStr to a DataTime object in DataTime buffer".

Thanks!

-----Original Message-----
From: Yao, Jiewen <jiewen.yao@intel.com> 
Sent: Monday, October 10, 2022 8:34 AM
To: Zhang, Qi1 <qi1.zhang@intel.com>; devel@edk2.groups.io
Cc: Wang, Jian J <jian.j.wang@intel.com>; Lu, Xiaoyu1 <xiaoyu1.lu@intel.com>; Jiang, Guomin <guomin.jiang@intel.com>
Subject: RE: [PATCH 1/4] CryptoPkg: add new X509 function definition.

Hi
I feel the function name X509SetDateTime() is very confusing. From the function comment, it means: "Format a DateTime object into DataTime Buffer".

I also find the comment in X509GetValidity(), "x509SetDateTime to get a DateTime object from a DateTimeStr"

It seems "DataTimeStr" is " DateTime string like YYYYMMDDhhmmssZ "
So what is the relationship among "DateTime object", "DateTime Buffer", and "DateTime Str" ?




> -----Original Message-----
> From: Zhang, Qi1 <qi1.zhang@intel.com>
> Sent: Sunday, September 25, 2022 4:54 PM
> To: devel@edk2.groups.io
> Cc: Zhang, Qi1 <qi1.zhang@intel.com>; Yao, Jiewen 
> <jiewen.yao@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Lu, 
> Xiaoyu1 <xiaoyu1.lu@intel.com>; Jiang, Guomin <guomin.jiang@intel.com>
> Subject: [PATCH 1/4] CryptoPkg: add new X509 function definition.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4082
> 
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
> Cc: Guomin Jiang <guomin.jiang@intel.com>
> Signed-off-by: Qi Zhang <qi1.zhang@intel.com>
> ---
>  CryptoPkg/Include/Library/BaseCryptLib.h | 374
> +++++++++++++++++++++++
>  1 file changed, 374 insertions(+)
> 
> diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h
> b/CryptoPkg/Include/Library/BaseCryptLib.h
> index 3026299e29..d7bf29c93f 100644
> --- a/CryptoPkg/Include/Library/BaseCryptLib.h
> +++ b/CryptoPkg/Include/Library/BaseCryptLib.h
> @@ -2459,6 +2459,380 @@ ImageTimestampVerify (
>    OUT EFI_TIME     *SigningTime
> 
>    );
> 
> 
> 
> +/**
> 
> +  Retrieve the version from one X.509 certificate.
> 
> +
> 
> +  If Cert is NULL, then return FALSE.
> 
> +  If CertSize is 0, then return FALSE.
> 
> +  If this interface is not supported, then return FALSE.
> 
> +
> 
> +  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
> 
> +  @param[in]      CertSize     Size of the X509 certificate in bytes.
> 
> +  @param[out]     Version      Pointer to the retrieved version integer.
> 
> +
> 
> +  @retval TRUE           The certificate version retrieved successfully.
> 
> +  @retval FALSE          If  Cert is NULL or CertSize is Zero.
> 
> +  @retval FALSE          The operation is not supported.
> 
> +
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetVersion (
> 
> +  IN      CONST UINT8  *Cert,
> 
> +  IN      UINTN        CertSize,
> 
> +  OUT     UINTN        *Version
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Retrieve the serialNumber from one X.509 certificate.
> 
> +
> 
> +  If Cert is NULL, then return FALSE.
> 
> +  If CertSize is 0, then return FALSE.
> 
> +  If this interface is not supported, then return FALSE.
> 
> +
> 
> +  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
> 
> +  @param[in]      CertSize     Size of the X509 certificate in bytes.
> 
> +  @param[out]     SerialNumber  Pointer to the retrieved certificate
> SerialNumber bytes.
> 
> +  @param[in, out] SerialNumberSize  The size in bytes of the 
> + SerialNumber
> buffer on input,
> 
> +                               and the size of buffer returned SerialNumber on output.
> 
> +
> 
> +  @retval TRUE                     The certificate serialNumber retrieved
> successfully.
> 
> +  @retval FALSE                    If Cert is NULL or CertSize is Zero.
> 
> +                                   If SerialNumberSize is NULL.
> 
> +                                   If Certificate is invalid.
> 
> +  @retval FALSE                    If no SerialNumber exists.
> 
> +  @retval FALSE                    If the SerialNumber is NULL. The required buffer
> size
> 
> +                                   (including the final null) is 
> + returned in the
> 
> +                                   SerialNumberSize parameter.
> 
> +  @retval FALSE                    The operation is not supported.
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetSerialNumber (
> 
> +  IN      CONST UINT8 *Cert,
> 
> +  IN      UINTN CertSize,
> 
> +  OUT     UINT8 *SerialNumber, OPTIONAL
> 
> +  IN OUT  UINTN         *SerialNumberSize
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Retrieve the issuer bytes from one X.509 certificate.
> 
> +
> 
> +  If Cert is NULL, then return FALSE.
> 
> +  If CertIssuerSize is NULL, then return FALSE.
> 
> +  If this interface is not supported, then return FALSE.
> 
> +
> 
> +  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
> 
> +  @param[in]      CertSize     Size of the X509 certificate in bytes.
> 
> +  @param[out]     CertIssuer  Pointer to the retrieved certificate subject
> bytes.
> 
> +  @param[in, out] CertIssuerSize  The size in bytes of the CertIssuer 
> + buffer
> on input,
> 
> +                               and the size of buffer returned CertSubject on output.
> 
> +
> 
> +  @retval  TRUE   The certificate issuer retrieved successfully.
> 
> +  @retval  FALSE  Invalid certificate, or the CertIssuerSize is too 
> + small for
> the result.
> 
> +                  The CertIssuerSize will be updated with the required size.
> 
> +  @retval  FALSE  This interface is not supported.
> 
> +
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetIssuerName (
> 
> +  IN      CONST UINT8  *Cert,
> 
> +  IN      UINTN        CertSize,
> 
> +  OUT     UINT8        *CertIssuer,
> 
> +  IN OUT  UINTN        *CertIssuerSize
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Retrieve the Signature Algorithm from one X.509 certificate.
> 
> +
> 
> +  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
> 
> +  @param[in]      CertSize         Size of the X509 certificate in bytes.
> 
> +  @param[out]     Oid              Signature Algorithm Object identifier buffer.
> 
> +  @param[in,out]  OidSize          Signature Algorithm Object identifier buffer
> size
> 
> +
> 
> +  @retval TRUE           The certificate Extension data retrieved successfully.
> 
> +  @retval FALSE                    If Cert is NULL.
> 
> +                                   If OidSize is NULL.
> 
> +                                   If Oid is not NULL and *OidSize is 0.
> 
> +                                   If Certificate is invalid.
> 
> +  @retval FALSE                    If no SignatureType.
> 
> +  @retval FALSE                    If the Oid is NULL. The required buffer size
> 
> +                                   is returned in the OidSize.
> 
> +  @retval FALSE                    The operation is not supported.
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetSignatureAlgorithm (
> 
> +  IN CONST UINT8 *Cert,
> 
> +  IN       UINTN CertSize,
> 
> +  OUT   UINT8 *Oid, OPTIONAL
> 
> +  IN OUT   UINTN       *OidSize
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Retrieve Extension data from one X.509 certificate.
> 
> +
> 
> +  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
> 
> +  @param[in]      CertSize         Size of the X509 certificate in bytes.
> 
> +  @param[in]      Oid              Object identifier buffer
> 
> +  @param[in]      OidSize          Object identifier buffer size
> 
> +  @param[out]     ExtensionData    Extension bytes.
> 
> +  @param[in, out] ExtensionDataSize Extension bytes size.
> 
> +
> 
> +  @retval TRUE                     The certificate Extension data retrieved
> successfully.
> 
> +  @retval FALSE                    If Cert is NULL.
> 
> +                                   If ExtensionDataSize is NULL.
> 
> +                                   If ExtensionData is not NULL and 
> + *ExtensionDataSize is
> 0.
> 
> +                                   If Certificate is invalid.
> 
> +  @retval FALSE                    If no Extension entry match Oid.
> 
> +  @retval FALSE                    If the ExtensionData is NULL. The required
> buffer size
> 
> +                                   is returned in the ExtensionDataSize parameter.
> 
> +  @retval FALSE                    The operation is not supported.
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetExtensionData (
> 
> +  IN     CONST UINT8  *Cert,
> 
> +  IN     UINTN        CertSize,
> 
> +  IN     CONST UINT8  *Oid,
> 
> +  IN     UINTN        OidSize,
> 
> +  OUT UINT8           *ExtensionData,
> 
> +  IN OUT UINTN        *ExtensionDataSize
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Retrieve the Validity from one X.509 certificate
> 
> +
> 
> +  If Cert is NULL, then return FALSE.
> 
> +  If CertIssuerSize is NULL, then return FALSE.
> 
> +  If this interface is not supported, then return FALSE.
> 
> +
> 
> +  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
> 
> +  @param[in]      CertSize     Size of the X509 certificate in bytes.
> 
> +  @param[in]      From         notBefore Pointer to DateTime object.
> 
> +  @param[in,out]  FromSize     notBefore DateTime object size.
> 
> +  @param[in]      To           notAfter Pointer to DateTime object.
> 
> +  @param[in,out]  ToSize       notAfter DateTime object size.
> 
> +
> 
> +  Note: X509CompareDateTime to compare DateTime oject
> 
> +        x509SetDateTime to get a DateTime object from a DateTimeStr
> 
> +
> 
> +  @retval  TRUE   The certificate Validity retrieved successfully.
> 
> +  @retval  FALSE  Invalid certificate, or Validity retrieve failed.
> 
> +  @retval  FALSE  This interface is not supported.
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetValidity (
> 
> +  IN     CONST UINT8  *Cert,
> 
> +  IN     UINTN        CertSize,
> 
> +  IN     UINT8        *From,
> 
> +  IN OUT UINTN        *FromSize,
> 
> +  IN     UINT8        *To,
> 
> +  IN OUT UINTN        *ToSize
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Format a DateTime object into DataTime Buffer
> 
> +
> 
> +  If DateTimeStr is NULL, then return FALSE.
> 
> +  If DateTimeSize is NULL, then return FALSE.
> 
> +  If this interface is not supported, then return FALSE.
> 
> +
> 
> +  @param[in]      DateTimeStr      DateTime string like YYYYMMDDhhmmssZ
> 
> +                                   Ref: 
> + https://www.w3.org/TR/NOTE-datetime
> 
> +                                   Z stand for UTC time
> 
> +  @param[out]     DateTime         Pointer to a DateTime object.
> 
> +  @param[in,out]  DateTimeSize     DateTime object buffer size.
> 
> +
> 
> +  @retval TRUE                     The DateTime object create successfully.
> 
> +  @retval FALSE                    If DateTimeStr is NULL.
> 
> +                                   If DateTimeSize is NULL.
> 
> +                                   If DateTime is not NULL and *DateTimeSize is 0.
> 
> +                                   If Year Month Day Hour Minute 
> + Second combination is
> invalid datetime.
> 
> +  @retval FALSE                    If the DateTime is NULL. The required buffer
> size
> 
> +                                   (including the final null) is 
> + returned in the
> 
> +                                   DateTimeSize parameter.
> 
> +  @retval FALSE                    The operation is not supported.
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509SetDateTime (
> 
> +  IN   CHAR8    *DateTimeStr,
> 
> +  OUT  VOID     *DateTime,
> 
> +  IN OUT UINTN  *DateTimeSize
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Compare DateTime1 object and DateTime2 object.
> 
> +
> 
> +  If DateTime1 is NULL, then return -2.
> 
> +  If DateTime2 is NULL, then return -2.
> 
> +  If DateTime1 == DateTime2, then return 0
> 
> +  If DateTime1 > DateTime2, then return 1
> 
> +  If DateTime1 < DateTime2, then return -1
> 
> +
> 
> +  @param[in]      DateTime1         Pointer to a DateTime Ojbect
> 
> +  @param[in]      DateTime2         Pointer to a DateTime Object
> 
> +
> 
> +  @retval  0      If DateTime1 == DateTime2
> 
> +  @retval  1      If DateTime1 > DateTime2
> 
> +  @retval  -1     If DateTime1 < DateTime2
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +X509CompareDateTime (
> 
> +  IN  CONST  VOID  *DateTime1,
> 
> +  IN  CONST  VOID  *DateTime2
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Retrieve the Key Usage from one X.509 certificate.
> 
> +
> 
> +  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
> 
> +  @param[in]      CertSize         Size of the X509 certificate in bytes.
> 
> +  @param[out]     Usage            Key Usage (CRYPTO_X509_KU_*)
> 
> +
> 
> +  @retval  TRUE   The certificate Key Usage retrieved successfully.
> 
> +  @retval  FALSE  Invalid certificate, or Usage is NULL
> 
> +  @retval  FALSE  This interface is not supported.
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetKeyUsage (
> 
> +  IN    CONST UINT8  *Cert,
> 
> +  IN    UINTN        CertSize,
> 
> +  OUT   UINTN        *Usage
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Retrieve the Extended Key Usage from one X.509 certificate.
> 
> +
> 
> +  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
> 
> +  @param[in]      CertSize         Size of the X509 certificate in bytes.
> 
> +  @param[out]     Usage            Key Usage bytes.
> 
> +  @param[in, out] UsageSize        Key Usage buffer sizs in bytes.
> 
> +
> 
> +  @retval TRUE                     The Usage bytes retrieve successfully.
> 
> +  @retval FALSE                    If Cert is NULL.
> 
> +                                   If CertSize is NULL.
> 
> +                                   If Usage is not NULL and *UsageSize is 0.
> 
> +                                   If Cert is invalid.
> 
> +  @retval FALSE                    If the Usage is NULL. The required buffer size
> 
> +                                   is returned in the UsageSize parameter.
> 
> +  @retval FALSE                    The operation is not supported.
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetExtendedKeyUsage (
> 
> +  IN     CONST UINT8  *Cert,
> 
> +  IN     UINTN        CertSize,
> 
> +  OUT UINT8           *Usage,
> 
> +  IN OUT UINTN        *UsageSize
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Verify one X509 certificate was issued by the trusted CA.
> 
> +  @param[in]      RootCert          Trusted Root Certificate buffer
> 
> +
> 
> +  @param[in]      RootCertLength    Trusted Root Certificate buffer length
> 
> +  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509
> certificates
> 
> +                                    where the first certificate is 
> + signed by the Root
> 
> +                                    Certificate or is the Root 
> + Cerificate itself. and
> 
> +                                    subsequent cerificate is signed 
> + by the preceding
> 
> +                                    cerificate.
> 
> +  @param[in]      CertChainLength   Total length of the certificate chain, in
> bytes.
> 
> +
> 
> +  @retval  TRUE   All cerificates was issued by the first certificate in
> X509Certchain.
> 
> +  @retval  FALSE  Invalid certificate or the certificate was not 
> + issued by the
> given
> 
> +                  trusted CA.
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509VerifyCertChain (
> 
> +  IN CONST UINT8  *RootCert,
> 
> +  IN UINTN        RootCertLength,
> 
> +  IN CONST UINT8  *CertChain,
> 
> +  IN UINTN        CertChainLength
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Get one X509 certificate from CertChain.
> 
> +
> 
> +  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509
> certificates
> 
> +                                    where the first certificate is 
> + signed by the Root
> 
> +                                    Certificate or is the Root 
> + Cerificate itself. and
> 
> +                                    subsequent cerificate is signed 
> + by the preceding
> 
> +                                    cerificate.
> 
> +  @param[in]      CertChainLength   Total length of the certificate chain, in
> bytes.
> 
> +
> 
> +  @param[in]      CertIndex         Index of certificate. If index is -1 indecate
> the
> 
> +                                    last certificate in CertChain.
> 
> +
> 
> +  @param[out]     Cert              The certificate at the index of CertChain.
> 
> +  @param[out]     CertLength        The length certificate at the index of
> CertChain.
> 
> +
> 
> +  @retval  TRUE   Success.
> 
> +  @retval  FALSE  Failed to get certificate from certificate chain.
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetCertFromCertChain (
> 
> +  IN CONST UINT8   *CertChain,
> 
> +  IN UINTN         CertChainLength,
> 
> +  IN CONST INT32   CertIndex,
> 
> +  OUT CONST UINT8  **Cert,
> 
> +  OUT UINTN        *CertLength
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Retrieve the tag and length of the tag.
> 
> +
> 
> +  @param Ptr      The position in the ASN.1 data
> 
> +  @param End      End of data
> 
> +  @param Length   The variable that will receive the length
> 
> +  @param Tag      The expected tag
> 
> +
> 
> +  @retval      TRUE   Get tag successful
> 
> +  @retval      FALSe  Failed to get tag or tag not match
> 
> +**/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +Asn1GetTag (
> 
> +  IN OUT UINT8   **Ptr,
> 
> +  IN     UINT8   *End,
> 
> +  OUT UINTN      *Length,
> 
> +  IN     UINT32  Tag
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Retrieve the basic constraints from one X.509 certificate.
> 
> +
> 
> +  @param[in]      Cert                     Pointer to the DER-encoded X509
> certificate.
> 
> +  @param[in]      CertSize                 size of the X509 certificate in bytes.
> 
> +  @param[out]     BasicConstraints         basic constraints bytes.
> 
> +  @param[in, out] BasicConstraintsSize     basic constraints buffer sizs in
> bytes.
> 
> +
> 
> +  @retval TRUE                     The basic constraints retrieve successfully.
> 
> +  @retval FALSE                    If cert is NULL.
> 
> +                                   If cert_size is NULL.
> 
> +                                   If basic_constraints is not NULL 
> + and
> *basic_constraints_size is 0.
> 
> +                                   If cert is invalid.
> 
> +  @retval FALSE                    The required buffer size is small.
> 
> +                                   The return buffer size is 
> + basic_constraints_size
> parameter.
> 
> +  @retval FALSE                    If no Extension entry match oid.
> 
> +  @retval FALSE                    The operation is not supported.
> 
> + **/
> 
> +BOOLEAN
> 
> +EFIAPI
> 
> +X509GetExtendedBasicConstraints             (
> 
> +  CONST UINT8  *Cert,
> 
> +  UINTN        CertSize,
> 
> +  UINT8        *BasicConstraints,
> 
> +  UINTN        *BasicConstraintsSize
> 
> +  );
> 
> +
> 
>  //
> ==========================================================
> ===========================
> 
>  //    DH Key Exchange Primitive
> 
>  //
> ==========================================================
> ===========================
> 
> --
> 2.26.2.windows.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-10-10  4:30 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-25  8:54 [PATCH 0/4] CryptoPkg: add more X509 functions Qi Zhang
2022-09-25  8:54 ` [PATCH 1/4] CryptoPkg: add new X509 function definition Qi Zhang
2022-10-10  0:34   ` Yao, Jiewen
2022-10-10  4:30     ` Qi Zhang
2022-09-25  8:54 ` [PATCH 2/4] CryptoPkg: add new X509 function Qi Zhang
2022-09-25  8:54 ` [PATCH 3/4] CryptoPkg: add new X509 function to Crypto Service Qi Zhang
2022-09-25  8:54 ` [PATCH 4/4] CryptoPkg: add Unit Test for X509 new function Qi Zhang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox